diff --git a/.gitignore b/.gitignore
index 0d943eb8b6eb301297b8824895349cd6ba0b8ef5..78d27955d66cf5bd0f9ee2c0e83c26f17b973601 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,5 +73,131 @@ build
 install
 */install
 
+
+# Created by https://www.gitignore.io/api/python
+# Edit at https://www.gitignore.io/?templates=python
+
+### Python ###
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+### Python Patch ###
+.venv/
+
+# End of https://www.gitignore.io/api/python
+
 # Jupyter ignores
 .ipynb_checkpoints
diff --git a/.travis.yml b/.travis.yml
index 894f33f0b0186120a16aebe13ded9dc11dac3592..4930abcbe34d312c92940c76a239dc1257f134c6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,10 +39,13 @@ install:
     fi
   - bash miniconda.sh -b -p $HOME/miniconda
   - export PATH="$HOME/miniconda/bin:$PATH"
-  - conda env create -f environment.yml -n eal
-  - source activate eal
+  - conda config --set always_yes yes
+  - conda env create -f environment.yml -n ale
+  - source activate ale
+  - conda install pytest
 
 script:
+  - PYTHONPATH=. pytest tests/pytests
   - mkdir build
   - cd build
   - cmake -DCOVERAGE=ON ..
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7322103b8ff2538a08455e698c6978986c78ad1f..b2124098d26eaa850e5bd3f2fd42994fd7485a35 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,13 @@
 
 #===============================================================================
-#      The main build file for building EAL using CMake.
+#      The main build file for building ale using CMake.
 #===============================================================================
 # CMake initialization
 
 # Specify the required version of CMake.
 # cmake 3.10 required for ctest/gtest integration
 cmake_minimum_required(VERSION 3.10)
-project(eal VERSION 0.0.1 DESCRIPTION "Ephemeris Abstraction Library")
+project(ale VERSION 0.0.1 DESCRIPTION "Abstraction Library for Ephemerides ")
 
 # include what we need
 include(GNUInstallDirs)
@@ -22,24 +22,24 @@ find_package(GSL    REQUIRED)
 find_package(Eigen3 3.3 REQUIRED NO_MODULE)
 
 # Library setup
-add_library(eal SHARED
-            ${CMAKE_CURRENT_SOURCE_DIR}/src/eal.cpp)
-set_target_properties(eal PROPERTIES
+add_library(ale SHARED
+            ${CMAKE_CURRENT_SOURCE_DIR}/src/ale.cpp)
+set_target_properties(ale PROPERTIES
     VERSION ${PROJECT_VERSION}
     SOVERSION 1)
-set(EAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include/"
+set(ALE_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include/"
                      "${CMAKE_CURRENT_SOURCE_DIR}/include/json")
 
-target_include_directories(eal
+target_include_directories(ale
                            PRIVATE
                            ${GSL_INCLUDE_DIRS}
                            ${EIGEN3_INCLUDE_DIR}
                            PUBLIC
-                           ${EAL_INCLUDE_DIRS})
+                          ${ALE_INCLUDE_DIRS})
 
 # Setup for GoogleTest
 find_package (Threads)
-target_link_libraries(eal
+target_link_libraries(ale
                       PRIVATE
                       ${GSL_LIBRARIES}
                       PUBLIC
@@ -47,16 +47,16 @@ target_link_libraries(eal
 
 # Setup for ctest
 enable_testing()
-add_subdirectory(tests)
+add_subdirectory(tests/ctests)
 
 # Setup for code coverage
 # default to off
 set(COVERAGE OFF CACHE BOOL "Coverage")
 if(COVERAGE)
-    target_compile_options(eal PRIVATE --coverage -O0)
-    target_link_libraries(eal PRIVATE --coverage -O0)
+    target_compile_options(ale PRIVATE --coverage -O0)
+    target_link_libraries(ale PRIVATE --coverage -O0)
 endif()
 
 # Install commands
-install(TARGETS eal LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
-install(DIRECTORY ${EAL_INCLUDE_DIRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+install(TARGETS ale LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+install(DIRECTORY ${ALE_INCLUDE_DIRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
diff --git a/ale/__init__.py b/ale/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7fdacb91804e55d9f53cf08f3c87f3c38973b819
--- /dev/null
+++ b/ale/__init__.py
@@ -0,0 +1 @@
+from . import drivers
diff --git a/minipf/config.py b/ale/config.py
similarity index 100%
rename from minipf/config.py
rename to ale/config.py
diff --git a/minipf/drivers/__init__.py b/ale/drivers/__init__.py
similarity index 89%
rename from minipf/drivers/__init__.py
rename to ale/drivers/__init__.py
index 137ebaf2d27cabca6bdb965e8a644070ea483b53..95a85ea50353e1c123fbad9d73e86bd0efb8b65d 100644
--- a/minipf/drivers/__init__.py
+++ b/ale/drivers/__init__.py
@@ -12,7 +12,7 @@ from abc import ABC
 
 # dynamically load drivers
 __all__ = [os.path.splitext(os.path.basename(d))[0] for d in glob(os.path.join(os.path.dirname(__file__), '*_driver.py'))]
-__driver_modules__ = [importlib.import_module('.'+m, package='minipf.drivers') for m in __all__]
+__driver_modules__ = [importlib.import_module('.'+m, package='ale.drivers') for m in __all__]
 
 drivers = dict(chain.from_iterable(inspect.getmembers(dmod, lambda x: inspect.isclass(x) and "_driver" in x.__module__) for dmod in __driver_modules__))
 
diff --git a/minipf/drivers/base.py b/ale/drivers/base.py
similarity index 98%
rename from minipf/drivers/base.py
rename to ale/drivers/base.py
index 92a270e9cf895436632e9eae1c79a2f2fff45251..f8ddbcd25b4ba647fff764771e2bf7910316117b 100644
--- a/minipf/drivers/base.py
+++ b/ale/drivers/base.py
@@ -5,8 +5,7 @@ import numpy as np
 import pvl
 import spiceypy as spice
 
-from minipf.drivers import distortion
-from minipf.models.isd200 import ISD200
+from ale.drivers import distortion
 
 class Base(ABC):
     """
@@ -55,10 +54,10 @@ class Base(ABC):
 
     def to_pfeffer_response(self):
         """
-        Parse the data into a valid minipf response
+        Parse the data into a valid ale response
         """
         data = self.to_dict()
-        # Take the flat reponse and create the minipf obj dicts
+        # Take the flat reponse and create the ale obj dicts
         data['detector_center'] = {'line': data['detector_center'][0],
                                 'sample': data['detector_center'][1]}
 
@@ -94,7 +93,7 @@ class Base(ABC):
 
         data['name_platform'] = data['spacecraft_name']
         data['name_sensor'] = data['instrument_id']
-        return ISD200.from_dict(data)
+        return data
 
     def _compute_ephemerides(self):
         """
diff --git a/minipf/drivers/cassini_driver.py b/ale/drivers/cassini_driver.py
similarity index 94%
rename from minipf/drivers/cassini_driver.py
rename to ale/drivers/cassini_driver.py
index 600187fb04145ee989aa995317ee1c2d8a96eeb9..cdde1173df63b6cf59e1f947190432fa9eb332c8 100644
--- a/minipf/drivers/cassini_driver.py
+++ b/ale/drivers/cassini_driver.py
@@ -5,9 +5,9 @@ import pvl
 import spiceypy as spice
 import numpy as np
 
-from minipf import config
-from minipf.drivers.base import Framer
-from minipf.drivers.distortion import RadialDistortion
+from ale import config
+from ale.drivers.base import Framer
+from ale.drivers.distortion import RadialDistortion
 
 
 class CassiniISS(Framer, RadialDistortion):
diff --git a/minipf/drivers/distortion.py b/ale/drivers/distortion.py
similarity index 85%
rename from minipf/drivers/distortion.py
rename to ale/drivers/distortion.py
index b55c06e78b2ef0694a6c9196478042c2f2b37ed2..3a5bac4d443af3750f03d3b8c7120d6e572d799f 100644
--- a/minipf/drivers/distortion.py
+++ b/ale/drivers/distortion.py
@@ -1,8 +1,6 @@
 from abc import ABC
 import spiceypy as spice
 
-from minipf.models.optical_distortion_transverse import OpticalDistortionTransverse
-
 
 class TransverseDistortion(ABC):
     """
@@ -11,8 +9,8 @@ class TransverseDistortion(ABC):
     @property
     def odtx(self):
         return spice.gdpool('INS{}_OD_T_X'.format(self.ikid),0, 10)
-    
-    @property 
+
+    @property
     def odty(self):
         return spice.gdpool('INS{}_OD_T_Y'.format(self.ikid), 0, 10)
 
@@ -22,4 +20,4 @@ class RadialDistortion(ABC):
     """
     @property
     def odtk(self):
-        return spice.gdpool('INS{}_OD_K'.format(self.ikid),0, 3)
\ No newline at end of file
+        return spice.gdpool('INS{}_OD_K'.format(self.ikid),0, 3)
diff --git a/minipf/drivers/lro_driver.py b/ale/drivers/lro_driver.py
similarity index 86%
rename from minipf/drivers/lro_driver.py
rename to ale/drivers/lro_driver.py
index a3043ff61aaf6627ba7b474b3c5558b19bec4db5..924662706a6091383ee32cb53d6c8788058a0dcf 100644
--- a/minipf/drivers/lro_driver.py
+++ b/ale/drivers/lro_driver.py
@@ -5,9 +5,9 @@ import numpy as np
 import pvl
 import spiceypy as spice
 
-from minipf.util import get_metakernels
-from minipf.drivers.base import LineScanner
-from minipf.drivers.distortion import RadialDistortion
+from ale.util import get_metakernels
+from ale.drivers.base import LineScanner
+from ale.drivers.distortion import RadialDistortion
 
 class LRO_LROC(LineScanner, RadialDistortion):
 
diff --git a/minipf/drivers/mdis_driver.py b/ale/drivers/mdis_driver.py
similarity index 93%
rename from minipf/drivers/mdis_driver.py
rename to ale/drivers/mdis_driver.py
index b014622bdb36de6fdea9d5f61e6d0d8c38ee8ee4..9971588b1adc75601333ffbe3b2e09947dc813cd 100644
--- a/minipf/drivers/mdis_driver.py
+++ b/ale/drivers/mdis_driver.py
@@ -5,9 +5,9 @@ import pvl
 import spiceypy as spice
 import numpy as np
 
-from minipf import config
-from minipf.drivers.base import Framer
-from minipf.drivers.distortion import TransverseDistortion
+from ale import config
+from ale.drivers.base import Framer
+from ale.drivers.distortion import TransverseDistortion
 
 
 class Messenger(Framer, TransverseDistortion):
diff --git a/minipf/drivers/mro_driver.py b/ale/drivers/mro_driver.py
similarity index 87%
rename from minipf/drivers/mro_driver.py
rename to ale/drivers/mro_driver.py
index c3a67546a691981c4cc95631c238e358ca43c3d2..ae5bc7bd873821e3b487219a5450baeb6f7a83e6 100644
--- a/minipf/drivers/mro_driver.py
+++ b/ale/drivers/mro_driver.py
@@ -4,10 +4,10 @@ import os
 import numpy as np
 import pvl
 import spiceypy as spice
-from minipf import config
+from ale import config
 
-from minipf.drivers.base import LineScanner
-from minipf.drivers.distortion import RadialDistortion
+from ale.drivers.base import LineScanner
+from ale.drivers.distortion import RadialDistortion
 
 class MRO_CTX(LineScanner, RadialDistortion):
     id_lookup = {
@@ -28,7 +28,7 @@ class MRO_CTX(LineScanner, RadialDistortion):
     @property
     def instrument_id(self):
         return self.id_lookup[self.label['INSTRUMENT_NAME']]
-    
+
     @property
     def spacecraft_name(self):
         name_lookup = {
diff --git a/environment.yml b/environment.yml
index a318f4895d9b2e7ed16c03e699da6e863a5dd88b..0532cf5dd86115fc6cf281517c46b93515efafd1 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,11 +1,15 @@
-name: eal
-
+name: ale
 channels:
   - conda-forge
   - default
 
 dependencies:
+  - python=3.7.1
   - cmake>=3.10
   - gsl
   - openblas>=0.3.0
   - eigen
+  - spiceypy
+  - numpy
+  - python-dateutil
+  - pvl
diff --git a/include/eal.h b/include/ale.h
similarity index 95%
rename from include/eal.h
rename to include/ale.h
index 37bdd000b7bfd9bce4f740547c251e0dc6c0c9a3..83e5ccea72fdeacc6eb3fc2865c2b98b4786f0a1 100644
--- a/include/eal.h
+++ b/include/ale.h
@@ -1,5 +1,5 @@
-#ifndef EAL_INCLUDE_EAL_H
-#define EAL_INCLUDE_EAL_H
+#ifndef ALE_INCLUDE_ALE_H
+#define ALE_INCLUDE_ALE_H
 
 #include <json.hpp>
 #include <string>
@@ -7,7 +7,7 @@
 
 #include <gsl/gsl_interp.h>
 
-namespace eal {
+namespace ale {
 
   enum interpolation {
     linear,
@@ -42,4 +42,4 @@ namespace eal {
   double interpolate(std::vector<double> points, std::vector<double> times, double time, interpolation interp, int d);
 }
 
-#endif // EAL_H
+#endif // ALE_H
diff --git a/minipf/__init__.py b/minipf/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/minipf/models/__init__.py b/minipf/models/__init__.py
deleted file mode 100644
index c1b09b02d91ab2f63bd1e2394442df1fca9e0467..0000000000000000000000000000000000000000
--- a/minipf/models/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# coding: utf-8
-
-# flake8: noqa
-from __future__ import absolute_import
-# import models into model package
-from minipf.models.data import Data
-from minipf.models.isd200 import ISD200
-from minipf.models.isd200_detector_center import ISD200DetectorCenter
-from minipf.models.isd200_focal_length_model import ISD200FocalLengthModel
-from minipf.models.isd200_radii import ISD200Radii
-from minipf.models.isd200_reference_height import ISD200ReferenceHeight
-from minipf.models.isd200_sensor_position import ISD200SensorPosition
-from minipf.models.isd200_sun_position import ISD200SunPosition
-from minipf.models.optical_distortion import OpticalDistortion
-from minipf.models.optical_distortion_radial import OpticalDistortionRadial
-from minipf.models.optical_distortion_transverse import OpticalDistortionTransverse
-from minipf.models.quaternions import Quaternions
-from minipf.models.request_isd import RequestISD
-from minipf.models.xyz import XYZ
diff --git a/minipf/models/base_model_.py b/minipf/models/base_model_.py
deleted file mode 100644
index 653500686d8af9ccfbca1f2718c603f17a3a3cb3..0000000000000000000000000000000000000000
--- a/minipf/models/base_model_.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import pprint
-
-import six
-import typing
-
-from minipf import util
-
-T = typing.TypeVar('T')
-
-
-class Model(object):
-    # openapiTypes: The key is attribute name and the
-    # value is attribute type.
-    openapi_types = {}
-
-    # attributeMap: The key is attribute name and the
-    # value is json key in definition.
-    attribute_map = {}
-
-    @classmethod
-    def from_dict(cls: typing.Type[T], dikt) -> T:
-        """Returns the dict as a model"""
-        return util.deserialize_model(dikt, cls)
-
-    def to_dict(self):
-        """Returns the model properties as a dict
-
-        :rtype: dict
-        """
-        result = {}
-
-        for attr, _ in six.iteritems(self.openapi_types):
-            value = getattr(self, attr)
-            if isinstance(value, list):
-                result[attr] = list(map(
-                    lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
-                    value
-                ))
-            elif hasattr(value, "to_dict"):
-                result[attr] = value.to_dict()
-            elif isinstance(value, dict):
-                result[attr] = dict(map(
-                    lambda item: (item[0], item[1].to_dict())
-                    if hasattr(item[1], "to_dict") else item,
-                    value.items()
-                ))
-            else:
-                result[attr] = value
-
-        return result
-
-    def to_str(self):
-        """Returns the string representation of the model
-
-        :rtype: str
-        """
-        return pprint.pformat(self.to_dict())
-
-    def __repr__(self):
-        """For `print` and `pprint`"""
-        return self.to_str()
-
-    def __eq__(self, other):
-        """Returns true if both objects are equal"""
-        return self.__dict__ == other.__dict__
-
-    def __ne__(self, other):
-        """Returns true if both objects are not equal"""
-        return not self == other
diff --git a/minipf/models/data.py b/minipf/models/data.py
deleted file mode 100644
index 5ffae905c277eb45fca9ad620c94ce13dd70881e..0000000000000000000000000000000000000000
--- a/minipf/models/data.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class Data(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, count: int=None, data: List[object]=None):  # noqa: E501
-        """Data - a model defined in OpenAPI
-
-        :param count: The count of this Data.  # noqa: E501
-        :type count: int
-        :param data: The data of this Data.  # noqa: E501
-        :type data: List[object]
-        """
-        self.openapi_types = {
-            'count': int,
-            'data': List[object]
-        }
-
-        self.attribute_map = {
-            'count': 'count',
-            'data': 'data'
-        }
-
-        self._count = count
-        self._data = data
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'Data':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The data of this Data.  # noqa: E501
-        :rtype: Data
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def count(self) -> int:
-        """Gets the count of this Data.
-
-
-        :return: The count of this Data.
-        :rtype: int
-        """
-        return self._count
-
-    @count.setter
-    def count(self, count: int):
-        """Sets the count of this Data.
-
-
-        :param count: The count of this Data.
-        :type count: int
-        """
-
-        self._count = count
-
-    @property
-    def data(self) -> List[object]:
-        """Gets the data of this Data.
-
-
-        :return: The data of this Data.
-        :rtype: List[object]
-        """
-        return self._data
-
-    @data.setter
-    def data(self, data: List[object]):
-        """Sets the data of this Data.
-
-
-        :param data: The data of this Data.
-        :type data: List[object]
-        """
-
-        self._data = data
diff --git a/minipf/models/isd200.py b/minipf/models/isd200.py
deleted file mode 100644
index 51ad544078457f1175071e62ac2fd272988d5ca2..0000000000000000000000000000000000000000
--- a/minipf/models/isd200.py
+++ /dev/null
@@ -1,820 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf.models.isd200_detector_center import ISD200DetectorCenter  # noqa: F401,E501
-from minipf.models.isd200_focal_length_model import ISD200FocalLengthModel  # noqa: F401,E501
-from minipf.models.isd200_radii import ISD200Radii  # noqa: F401,E501
-from minipf.models.isd200_reference_height import ISD200ReferenceHeight  # noqa: F401,E501
-from minipf.models.isd200_sensor_position import ISD200SensorPosition  # noqa: F401,E501
-from minipf.models.isd200_sun_position import ISD200SunPosition  # noqa: F401,E501
-from minipf.models.optical_distortion import OpticalDistortion  # noqa: F401,E501
-from minipf.models.quaternions import Quaternions  # noqa: F401,E501
-from minipf import util
-
-
-class ISD200(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, name_platform: str=None, name_sensor: str=None, detector_center: ISD200DetectorCenter=None, center_ephemeris_time: float=None, name_model: str=None, starting_ephemeris_time: float=None, focal_length_model: ISD200FocalLengthModel=None, image_lines: float=None, image_samples: float=None, radii: ISD200Radii=None, optical_distortion: OpticalDistortion=None, starting_detector_sample: float=None, starting_detector_line: float=None, focal2pixel_samples: List[float]=None, focal2pixel_lines: List[float]=None, sensor_position: ISD200SensorPosition=None, sun_position: ISD200SunPosition=None, sensor_orientation: Quaternions=None, line_scan_rate: List[List[float]]=None, detector_sample_summing: float=None, detector_line_summing: float=None, dt_ephemeris: float=None, t0_ephemeris: float=None, dt_quaternion: float=None, t0_quaternion: float=None, reference_height: ISD200ReferenceHeight=None, interpolation_method: str=None):  # noqa: E501
-        """ISD200 - a model defined in OpenAPI
-
-        :param name_platform: The name_platform of this ISD200.  # noqa: E501
-        :type name_platform: str
-        :param name_sensor: The name_sensor of this ISD200.  # noqa: E501
-        :type name_sensor: str
-        :param detector_center: The detector_center of this ISD200.  # noqa: E501
-        :type detector_center: ISD200DetectorCenter
-        :param center_ephemeris_time: The center_ephemeris_time of this ISD200.  # noqa: E501
-        :type center_ephemeris_time: float
-        :param name_model: The name_model of this ISD200.  # noqa: E501
-        :type name_model: str
-        :param starting_ephemeris_time: The starting_ephemeris_time of this ISD200.  # noqa: E501
-        :type starting_ephemeris_time: float
-        :param focal_length_model: The focal_length_model of this ISD200.  # noqa: E501
-        :type focal_length_model: ISD200FocalLengthModel
-        :param image_lines: The image_lines of this ISD200.  # noqa: E501
-        :type image_lines: float
-        :param image_samples: The image_samples of this ISD200.  # noqa: E501
-        :type image_samples: float
-        :param radii: The radii of this ISD200.  # noqa: E501
-        :type radii: ISD200Radii
-        :param optical_distortion: The optical_distortion of this ISD200.  # noqa: E501
-        :type optical_distortion: OpticalDistortion
-        :param starting_detector_sample: The starting_detector_sample of this ISD200.  # noqa: E501
-        :type starting_detector_sample: float
-        :param starting_detector_line: The starting_detector_line of this ISD200.  # noqa: E501
-        :type starting_detector_line: float
-        :param focal2pixel_samples: The focal2pixel_samples of this ISD200.  # noqa: E501
-        :type focal2pixel_samples: List[float]
-        :param focal2pixel_lines: The focal2pixel_lines of this ISD200.  # noqa: E501
-        :type focal2pixel_lines: List[float]
-        :param sensor_position: The sensor_position of this ISD200.  # noqa: E501
-        :type sensor_position: ISD200SensorPosition
-        :param sun_position: The sun_position of this ISD200.  # noqa: E501
-        :type sun_position: ISD200SunPosition
-        :param sensor_orientation: The sensor_orientation of this ISD200.  # noqa: E501
-        :type sensor_orientation: Quaternions
-        :param line_scan_rate: The line_scan_rate of this ISD200.  # noqa: E501
-        :type line_scan_rate: List[List[float]]
-        :param detector_sample_summing: The detector_sample_summing of this ISD200.  # noqa: E501
-        :type detector_sample_summing: float
-        :param detector_line_summing: The detector_line_summing of this ISD200.  # noqa: E501
-        :type detector_line_summing: float
-        :param dt_ephemeris: The dt_ephemeris of this ISD200.  # noqa: E501
-        :type dt_ephemeris: float
-        :param t0_ephemeris: The t0_ephemeris of this ISD200.  # noqa: E501
-        :type t0_ephemeris: float
-        :param dt_quaternion: The dt_quaternion of this ISD200.  # noqa: E501
-        :type dt_quaternion: float
-        :param t0_quaternion: The t0_quaternion of this ISD200.  # noqa: E501
-        :type t0_quaternion: float
-        :param reference_height: The reference_height of this ISD200.  # noqa: E501
-        :type reference_height: ISD200ReferenceHeight
-        :param interpolation_method: The interpolation_method of this ISD200.  # noqa: E501
-        :type interpolation_method: str
-        """
-        self.openapi_types = {
-            'name_platform': str,
-            'name_sensor': str,
-            'detector_center': ISD200DetectorCenter,
-            'center_ephemeris_time': float,
-            'name_model': str,
-            'starting_ephemeris_time': float,
-            'focal_length_model': ISD200FocalLengthModel,
-            'image_lines': float,
-            'image_samples': float,
-            'radii': ISD200Radii,
-            'optical_distortion': OpticalDistortion,
-            'starting_detector_sample': float,
-            'starting_detector_line': float,
-            'focal2pixel_samples': List[float],
-            'focal2pixel_lines': List[float],
-            'sensor_position': ISD200SensorPosition,
-            'sun_position': ISD200SunPosition,
-            'sensor_orientation': Quaternions,
-            'line_scan_rate': List[List[float]],
-            'detector_sample_summing': float,
-            'detector_line_summing': float,
-            'dt_ephemeris': float,
-            't0_ephemeris': float,
-            'dt_quaternion': float,
-            't0_quaternion': float,
-            'reference_height': ISD200ReferenceHeight,
-            'interpolation_method': str
-        }
-
-        self.attribute_map = {
-            'name_platform': 'name_platform',
-            'name_sensor': 'name_sensor',
-            'detector_center': 'detector_center',
-            'center_ephemeris_time': 'center_ephemeris_time',
-            'name_model': 'name_model',
-            'starting_ephemeris_time': 'starting_ephemeris_time',
-            'focal_length_model': 'focal_length_model',
-            'image_lines': 'image_lines',
-            'image_samples': 'image_samples',
-            'radii': 'radii',
-            'optical_distortion': 'optical_distortion',
-            'starting_detector_sample': 'starting_detector_sample',
-            'starting_detector_line': 'starting_detector_line',
-            'focal2pixel_samples': 'focal2pixel_samples',
-            'focal2pixel_lines': 'focal2pixel_lines',
-            'sensor_position': 'sensor_position',
-            'sun_position': 'sun_position',
-            'sensor_orientation': 'sensor_orientation',
-            'line_scan_rate': 'line_scan_rate',
-            'detector_sample_summing': 'detector_sample_summing',
-            'detector_line_summing': 'detector_line_summing',
-            'dt_ephemeris': 'dt_ephemeris',
-            't0_ephemeris': 't0_ephemeris',
-            'dt_quaternion': 'dt_quaternion',
-            't0_quaternion': 't0_quaternion',
-            'reference_height': 'reference_height',
-            'interpolation_method': 'interpolation_method'
-        }
-
-        self._name_platform = name_platform
-        self._name_sensor = name_sensor
-        self._detector_center = detector_center
-        self._center_ephemeris_time = center_ephemeris_time
-        self._name_model = name_model
-        self._starting_ephemeris_time = starting_ephemeris_time
-        self._focal_length_model = focal_length_model
-        self._image_lines = image_lines
-        self._image_samples = image_samples
-        self._radii = radii
-        self._optical_distortion = optical_distortion
-        self._starting_detector_sample = starting_detector_sample
-        self._starting_detector_line = starting_detector_line
-        self._focal2pixel_samples = focal2pixel_samples
-        self._focal2pixel_lines = focal2pixel_lines
-        self._sensor_position = sensor_position
-        self._sun_position = sun_position
-        self._sensor_orientation = sensor_orientation
-        self._line_scan_rate = line_scan_rate
-        self._detector_sample_summing = detector_sample_summing
-        self._detector_line_summing = detector_line_summing
-        self._dt_ephemeris = dt_ephemeris
-        self._t0_ephemeris = t0_ephemeris
-        self._dt_quaternion = dt_quaternion
-        self._t0_quaternion = t0_quaternion
-        self._reference_height = reference_height
-        self._interpolation_method = interpolation_method
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200 of this ISD200.  # noqa: E501
-        :rtype: ISD200
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def name_platform(self) -> str:
-        """Gets the name_platform of this ISD200.
-
-        The name of the sensor platform, e.g., the spacecraft.  # noqa: E501
-
-        :return: The name_platform of this ISD200.
-        :rtype: str
-        """
-        return self._name_platform
-
-    @name_platform.setter
-    def name_platform(self, name_platform: str):
-        """Sets the name_platform of this ISD200.
-
-        The name of the sensor platform, e.g., the spacecraft.  # noqa: E501
-
-        :param name_platform: The name_platform of this ISD200.
-        :type name_platform: str
-        """
-        if name_platform is None:
-            raise ValueError("Invalid value for `name_platform`, must not be `None`")  # noqa: E501
-
-        self._name_platform = name_platform
-
-    @property
-    def name_sensor(self) -> str:
-        """Gets the name_sensor of this ISD200.
-
-        The name of the sensor, e.g., MSGR_MDIS_NAC.  # noqa: E501
-
-        :return: The name_sensor of this ISD200.
-        :rtype: str
-        """
-        return self._name_sensor
-
-    @name_sensor.setter
-    def name_sensor(self, name_sensor: str):
-        """Sets the name_sensor of this ISD200.
-
-        The name of the sensor, e.g., MSGR_MDIS_NAC.  # noqa: E501
-
-        :param name_sensor: The name_sensor of this ISD200.
-        :type name_sensor: str
-        """
-        if name_sensor is None:
-            raise ValueError("Invalid value for `name_sensor`, must not be `None`")  # noqa: E501
-
-        self._name_sensor = name_sensor
-
-    @property
-    def detector_center(self) -> ISD200DetectorCenter:
-        """Gets the detector_center of this ISD200.
-
-
-        :return: The detector_center of this ISD200.
-        :rtype: ISD200DetectorCenter
-        """
-        return self._detector_center
-
-    @detector_center.setter
-    def detector_center(self, detector_center: ISD200DetectorCenter):
-        """Sets the detector_center of this ISD200.
-
-
-        :param detector_center: The detector_center of this ISD200.
-        :type detector_center: ISD200DetectorCenter
-        """
-
-        self._detector_center = detector_center
-
-    @property
-    def center_ephemeris_time(self) -> float:
-        """Gets the center_ephemeris_time of this ISD200.
-
-        The center ephemeris time of the image  # noqa: E501
-
-        :return: The center_ephemeris_time of this ISD200.
-        :rtype: float
-        """
-        return self._center_ephemeris_time
-
-    @center_ephemeris_time.setter
-    def center_ephemeris_time(self, center_ephemeris_time: float):
-        """Sets the center_ephemeris_time of this ISD200.
-
-        The center ephemeris time of the image  # noqa: E501
-
-        :param center_ephemeris_time: The center_ephemeris_time of this ISD200.
-        :type center_ephemeris_time: float
-        """
-
-        self._center_ephemeris_time = center_ephemeris_time
-
-    @property
-    def name_model(self) -> str:
-        """Gets the name_model of this ISD200.
-
-        The name of the model to be instantiated  # noqa: E501
-
-        :return: The name_model of this ISD200.
-        :rtype: str
-        """
-        return self._name_model
-
-    @name_model.setter
-    def name_model(self, name_model: str):
-        """Sets the name_model of this ISD200.
-
-        The name of the model to be instantiated  # noqa: E501
-
-        :param name_model: The name_model of this ISD200.
-        :type name_model: str
-        """
-        if name_model is None:
-            raise ValueError("Invalid value for `name_model`, must not be `None`")  # noqa: E501
-
-        self._name_model = name_model
-
-    @property
-    def starting_ephemeris_time(self) -> float:
-        """Gets the starting_ephemeris_time of this ISD200.
-
-        The starting ephemeris time of the image  # noqa: E501
-
-        :return: The starting_ephemeris_time of this ISD200.
-        :rtype: float
-        """
-        return self._starting_ephemeris_time
-
-    @starting_ephemeris_time.setter
-    def starting_ephemeris_time(self, starting_ephemeris_time: float):
-        """Sets the starting_ephemeris_time of this ISD200.
-
-        The starting ephemeris time of the image  # noqa: E501
-
-        :param starting_ephemeris_time: The starting_ephemeris_time of this ISD200.
-        :type starting_ephemeris_time: float
-        """
-        if starting_ephemeris_time is None:
-            raise ValueError("Invalid value for `starting_ephemeris_time`, must not be `None`")  # noqa: E501
-
-        self._starting_ephemeris_time = starting_ephemeris_time
-
-    @property
-    def focal_length_model(self) -> ISD200FocalLengthModel:
-        """Gets the focal_length_model of this ISD200.
-
-
-        :return: The focal_length_model of this ISD200.
-        :rtype: ISD200FocalLengthModel
-        """
-        return self._focal_length_model
-
-    @focal_length_model.setter
-    def focal_length_model(self, focal_length_model: ISD200FocalLengthModel):
-        """Sets the focal_length_model of this ISD200.
-
-
-        :param focal_length_model: The focal_length_model of this ISD200.
-        :type focal_length_model: ISD200FocalLengthModel
-        """
-        if focal_length_model is None:
-            raise ValueError("Invalid value for `focal_length_model`, must not be `None`")  # noqa: E501
-
-        self._focal_length_model = focal_length_model
-
-    @property
-    def image_lines(self) -> float:
-        """Gets the image_lines of this ISD200.
-
-        The number of lines in the image  # noqa: E501
-
-        :return: The image_lines of this ISD200.
-        :rtype: float
-        """
-        return self._image_lines
-
-    @image_lines.setter
-    def image_lines(self, image_lines: float):
-        """Sets the image_lines of this ISD200.
-
-        The number of lines in the image  # noqa: E501
-
-        :param image_lines: The image_lines of this ISD200.
-        :type image_lines: float
-        """
-        if image_lines is None:
-            raise ValueError("Invalid value for `image_lines`, must not be `None`")  # noqa: E501
-
-        self._image_lines = image_lines
-
-    @property
-    def image_samples(self) -> float:
-        """Gets the image_samples of this ISD200.
-
-        The the number of samples in the image  # noqa: E501
-
-        :return: The image_samples of this ISD200.
-        :rtype: float
-        """
-        return self._image_samples
-
-    @image_samples.setter
-    def image_samples(self, image_samples: float):
-        """Sets the image_samples of this ISD200.
-
-        The the number of samples in the image  # noqa: E501
-
-        :param image_samples: The image_samples of this ISD200.
-        :type image_samples: float
-        """
-        if image_samples is None:
-            raise ValueError("Invalid value for `image_samples`, must not be `None`")  # noqa: E501
-
-        self._image_samples = image_samples
-
-    @property
-    def radii(self) -> ISD200Radii:
-        """Gets the radii of this ISD200.
-
-
-        :return: The radii of this ISD200.
-        :rtype: ISD200Radii
-        """
-        return self._radii
-
-    @radii.setter
-    def radii(self, radii: ISD200Radii):
-        """Sets the radii of this ISD200.
-
-
-        :param radii: The radii of this ISD200.
-        :type radii: ISD200Radii
-        """
-        if radii is None:
-            raise ValueError("Invalid value for `radii`, must not be `None`")  # noqa: E501
-
-        self._radii = radii
-
-    @property
-    def optical_distortion(self) -> OpticalDistortion:
-        """Gets the optical_distortion of this ISD200.
-
-
-        :return: The optical_distortion of this ISD200.
-        :rtype: OpticalDistortion
-        """
-        return self._optical_distortion
-
-    @optical_distortion.setter
-    def optical_distortion(self, optical_distortion: OpticalDistortion):
-        """Sets the optical_distortion of this ISD200.
-
-
-        :param optical_distortion: The optical_distortion of this ISD200.
-        :type optical_distortion: OpticalDistortion
-        """
-
-        self._optical_distortion = optical_distortion
-
-    @property
-    def starting_detector_sample(self) -> float:
-        """Gets the starting_detector_sample of this ISD200.
-
-        The sample on the detector where the data starts  # noqa: E501
-
-        :return: The starting_detector_sample of this ISD200.
-        :rtype: float
-        """
-        return self._starting_detector_sample
-
-    @starting_detector_sample.setter
-    def starting_detector_sample(self, starting_detector_sample: float):
-        """Sets the starting_detector_sample of this ISD200.
-
-        The sample on the detector where the data starts  # noqa: E501
-
-        :param starting_detector_sample: The starting_detector_sample of this ISD200.
-        :type starting_detector_sample: float
-        """
-        if starting_detector_sample is None:
-            raise ValueError("Invalid value for `starting_detector_sample`, must not be `None`")  # noqa: E501
-
-        self._starting_detector_sample = starting_detector_sample
-
-    @property
-    def starting_detector_line(self) -> float:
-        """Gets the starting_detector_line of this ISD200.
-
-        The line on the detector where the data starts  # noqa: E501
-
-        :return: The starting_detector_line of this ISD200.
-        :rtype: float
-        """
-        return self._starting_detector_line
-
-    @starting_detector_line.setter
-    def starting_detector_line(self, starting_detector_line: float):
-        """Sets the starting_detector_line of this ISD200.
-
-        The line on the detector where the data starts  # noqa: E501
-
-        :param starting_detector_line: The starting_detector_line of this ISD200.
-        :type starting_detector_line: float
-        """
-        if starting_detector_line is None:
-            raise ValueError("Invalid value for `starting_detector_line`, must not be `None`")  # noqa: E501
-
-        self._starting_detector_line = starting_detector_line
-
-    @property
-    def focal2pixel_samples(self) -> List[float]:
-        """Gets the focal2pixel_samples of this ISD200.
-
-        Transformation x coefficients from focal plane (mm) to detector pixel coordinates  # noqa: E501
-
-        :return: The focal2pixel_samples of this ISD200.
-        :rtype: List[float]
-        """
-        return self._focal2pixel_samples
-
-    @focal2pixel_samples.setter
-    def focal2pixel_samples(self, focal2pixel_samples: List[float]):
-        """Sets the focal2pixel_samples of this ISD200.
-
-        Transformation x coefficients from focal plane (mm) to detector pixel coordinates  # noqa: E501
-
-        :param focal2pixel_samples: The focal2pixel_samples of this ISD200.
-        :type focal2pixel_samples: List[float]
-        """
-        if focal2pixel_samples is None:
-            raise ValueError("Invalid value for `focal2pixel_samples`, must not be `None`")  # noqa: E501
-
-        self._focal2pixel_samples = focal2pixel_samples
-
-    @property
-    def focal2pixel_lines(self) -> List[float]:
-        """Gets the focal2pixel_lines of this ISD200.
-
-        Transformation y coefficients from focal plane (mm) to detector pixel coordinates  # noqa: E501
-
-        :return: The focal2pixel_lines of this ISD200.
-        :rtype: List[float]
-        """
-        return self._focal2pixel_lines
-
-    @focal2pixel_lines.setter
-    def focal2pixel_lines(self, focal2pixel_lines: List[float]):
-        """Sets the focal2pixel_lines of this ISD200.
-
-        Transformation y coefficients from focal plane (mm) to detector pixel coordinates  # noqa: E501
-
-        :param focal2pixel_lines: The focal2pixel_lines of this ISD200.
-        :type focal2pixel_lines: List[float]
-        """
-        if focal2pixel_lines is None:
-            raise ValueError("Invalid value for `focal2pixel_lines`, must not be `None`")  # noqa: E501
-
-        self._focal2pixel_lines = focal2pixel_lines
-
-    @property
-    def sensor_position(self) -> ISD200SensorPosition:
-        """Gets the sensor_position of this ISD200.
-
-
-        :return: The sensor_position of this ISD200.
-        :rtype: ISD200SensorPosition
-        """
-        return self._sensor_position
-
-    @sensor_position.setter
-    def sensor_position(self, sensor_position: ISD200SensorPosition):
-        """Sets the sensor_position of this ISD200.
-
-
-        :param sensor_position: The sensor_position of this ISD200.
-        :type sensor_position: ISD200SensorPosition
-        """
-
-        self._sensor_position = sensor_position
-
-    @property
-    def sun_position(self) -> ISD200SunPosition:
-        """Gets the sun_position of this ISD200.
-
-
-        :return: The sun_position of this ISD200.
-        :rtype: ISD200SunPosition
-        """
-        return self._sun_position
-
-    @sun_position.setter
-    def sun_position(self, sun_position: ISD200SunPosition):
-        """Sets the sun_position of this ISD200.
-
-
-        :param sun_position: The sun_position of this ISD200.
-        :type sun_position: ISD200SunPosition
-        """
-
-        self._sun_position = sun_position
-
-    @property
-    def sensor_orientation(self) -> Quaternions:
-        """Gets the sensor_orientation of this ISD200.
-
-
-        :return: The sensor_orientation of this ISD200.
-        :rtype: Quaternions
-        """
-        return self._sensor_orientation
-
-    @sensor_orientation.setter
-    def sensor_orientation(self, sensor_orientation: Quaternions):
-        """Sets the sensor_orientation of this ISD200.
-
-
-        :param sensor_orientation: The sensor_orientation of this ISD200.
-        :type sensor_orientation: Quaternions
-        """
-        if sensor_orientation is None:
-            raise ValueError("Invalid value for `sensor_orientation`, must not be `None`")  # noqa: E501
-
-        self._sensor_orientation = sensor_orientation
-
-    @property
-    def line_scan_rate(self) -> List[List[float]]:
-        """Gets the line_scan_rate of this ISD200.
-
-        The line rates of the detector map with the associated start line and time  # noqa: E501
-
-        :return: The line_scan_rate of this ISD200.
-        :rtype: List[List[float]]
-        """
-        return self._line_scan_rate
-
-    @line_scan_rate.setter
-    def line_scan_rate(self, line_scan_rate: List[List[float]]):
-        """Sets the line_scan_rate of this ISD200.
-
-        The line rates of the detector map with the associated start line and time  # noqa: E501
-
-        :param line_scan_rate: The line_scan_rate of this ISD200.
-        :type line_scan_rate: List[List[float]]
-        """
-
-        self._line_scan_rate = line_scan_rate
-
-    @property
-    def detector_sample_summing(self) -> float:
-        """Gets the detector_sample_summing of this ISD200.
-
-        The summing in the sample-direction. A summing of 1 indicates no summing, summing of 2 indicates 2 pixel summing,4 indicates 4 pixel summing, etc   # noqa: E501
-
-        :return: The detector_sample_summing of this ISD200.
-        :rtype: float
-        """
-        return self._detector_sample_summing
-
-    @detector_sample_summing.setter
-    def detector_sample_summing(self, detector_sample_summing: float):
-        """Sets the detector_sample_summing of this ISD200.
-
-        The summing in the sample-direction. A summing of 1 indicates no summing, summing of 2 indicates 2 pixel summing,4 indicates 4 pixel summing, etc   # noqa: E501
-
-        :param detector_sample_summing: The detector_sample_summing of this ISD200.
-        :type detector_sample_summing: float
-        """
-
-        self._detector_sample_summing = detector_sample_summing
-
-    @property
-    def detector_line_summing(self) -> float:
-        """Gets the detector_line_summing of this ISD200.
-
-        The summing in the line-direction  # noqa: E501
-
-        :return: The detector_line_summing of this ISD200.
-        :rtype: float
-        """
-        return self._detector_line_summing
-
-    @detector_line_summing.setter
-    def detector_line_summing(self, detector_line_summing: float):
-        """Sets the detector_line_summing of this ISD200.
-
-        The summing in the line-direction  # noqa: E501
-
-        :param detector_line_summing: The detector_line_summing of this ISD200.
-        :type detector_line_summing: float
-        """
-
-        self._detector_line_summing = detector_line_summing
-
-    @property
-    def dt_ephemeris(self) -> float:
-        """Gets the dt_ephemeris of this ISD200.
-
-        The time between each ephemeris point.  # noqa: E501
-
-        :return: The dt_ephemeris of this ISD200.
-        :rtype: float
-        """
-        return self._dt_ephemeris
-
-    @dt_ephemeris.setter
-    def dt_ephemeris(self, dt_ephemeris: float):
-        """Sets the dt_ephemeris of this ISD200.
-
-        The time between each ephemeris point.  # noqa: E501
-
-        :param dt_ephemeris: The dt_ephemeris of this ISD200.
-        :type dt_ephemeris: float
-        """
-
-        self._dt_ephemeris = dt_ephemeris
-
-    @property
-    def t0_ephemeris(self) -> float:
-        """Gets the t0_ephemeris of this ISD200.
-
-        First ephemeris time - center image time  # noqa: E501
-
-        :return: The t0_ephemeris of this ISD200.
-        :rtype: float
-        """
-        return self._t0_ephemeris
-
-    @t0_ephemeris.setter
-    def t0_ephemeris(self, t0_ephemeris: float):
-        """Sets the t0_ephemeris of this ISD200.
-
-        First ephemeris time - center image time  # noqa: E501
-
-        :param t0_ephemeris: The t0_ephemeris of this ISD200.
-        :type t0_ephemeris: float
-        """
-
-        self._t0_ephemeris = t0_ephemeris
-
-    @property
-    def dt_quaternion(self) -> float:
-        """Gets the dt_quaternion of this ISD200.
-
-        Time spacing of quaternions.  # noqa: E501
-
-        :return: The dt_quaternion of this ISD200.
-        :rtype: float
-        """
-        return self._dt_quaternion
-
-    @dt_quaternion.setter
-    def dt_quaternion(self, dt_quaternion: float):
-        """Sets the dt_quaternion of this ISD200.
-
-        Time spacing of quaternions.  # noqa: E501
-
-        :param dt_quaternion: The dt_quaternion of this ISD200.
-        :type dt_quaternion: float
-        """
-
-        self._dt_quaternion = dt_quaternion
-
-    @property
-    def t0_quaternion(self) -> float:
-        """Gets the t0_quaternion of this ISD200.
-
-        First quaternion time - center image time.  # noqa: E501
-
-        :return: The t0_quaternion of this ISD200.
-        :rtype: float
-        """
-        return self._t0_quaternion
-
-    @t0_quaternion.setter
-    def t0_quaternion(self, t0_quaternion: float):
-        """Sets the t0_quaternion of this ISD200.
-
-        First quaternion time - center image time.  # noqa: E501
-
-        :param t0_quaternion: The t0_quaternion of this ISD200.
-        :type t0_quaternion: float
-        """
-
-        self._t0_quaternion = t0_quaternion
-
-    @property
-    def reference_height(self) -> ISD200ReferenceHeight:
-        """Gets the reference_height of this ISD200.
-
-
-        :return: The reference_height of this ISD200.
-        :rtype: ISD200ReferenceHeight
-        """
-        return self._reference_height
-
-    @reference_height.setter
-    def reference_height(self, reference_height: ISD200ReferenceHeight):
-        """Sets the reference_height of this ISD200.
-
-
-        :param reference_height: The reference_height of this ISD200.
-        :type reference_height: ISD200ReferenceHeight
-        """
-        if reference_height is None:
-            raise ValueError("Invalid value for `reference_height`, must not be `None`")  # noqa: E501
-
-        self._reference_height = reference_height
-
-    @property
-    def interpolation_method(self) -> str:
-        """Gets the interpolation_method of this ISD200.
-
-        The type of interpolation method to use.  # noqa: E501
-
-        :return: The interpolation_method of this ISD200.
-        :rtype: str
-        """
-        return self._interpolation_method
-
-    @interpolation_method.setter
-    def interpolation_method(self, interpolation_method: str):
-        """Sets the interpolation_method of this ISD200.
-
-        The type of interpolation method to use.  # noqa: E501
-
-        :param interpolation_method: The interpolation_method of this ISD200.
-        :type interpolation_method: str
-        """
-        allowed_values = ["lagrange"]  # noqa: E501
-        if interpolation_method not in allowed_values:
-            raise ValueError(
-                "Invalid value for `interpolation_method` ({0}), must be one of {1}"
-                .format(interpolation_method, allowed_values)
-            )
-
-        self._interpolation_method = interpolation_method
diff --git a/minipf/models/isd200_detector_center.py b/minipf/models/isd200_detector_center.py
deleted file mode 100644
index c44ad37526cdd5bdd1fced939309c48b465f2d3b..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_detector_center.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class ISD200DetectorCenter(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, line: float=None, sample: float=None):  # noqa: E501
-        """ISD200DetectorCenter - a model defined in OpenAPI
-
-        :param line: The line of this ISD200DetectorCenter.  # noqa: E501
-        :type line: float
-        :param sample: The sample of this ISD200DetectorCenter.  # noqa: E501
-        :type sample: float
-        """
-        self.openapi_types = {
-            'line': float,
-            'sample': float
-        }
-
-        self.attribute_map = {
-            'line': 'line',
-            'sample': 'sample'
-        }
-
-        self._line = line
-        self._sample = sample
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200DetectorCenter':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_detector_center of this ISD200DetectorCenter.  # noqa: E501
-        :rtype: ISD200DetectorCenter
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def line(self) -> float:
-        """Gets the line of this ISD200DetectorCenter.
-
-
-        :return: The line of this ISD200DetectorCenter.
-        :rtype: float
-        """
-        return self._line
-
-    @line.setter
-    def line(self, line: float):
-        """Sets the line of this ISD200DetectorCenter.
-
-
-        :param line: The line of this ISD200DetectorCenter.
-        :type line: float
-        """
-        if line is None:
-            raise ValueError("Invalid value for `line`, must not be `None`")  # noqa: E501
-
-        self._line = line
-
-    @property
-    def sample(self) -> float:
-        """Gets the sample of this ISD200DetectorCenter.
-
-
-        :return: The sample of this ISD200DetectorCenter.
-        :rtype: float
-        """
-        return self._sample
-
-    @sample.setter
-    def sample(self, sample: float):
-        """Sets the sample of this ISD200DetectorCenter.
-
-
-        :param sample: The sample of this ISD200DetectorCenter.
-        :type sample: float
-        """
-        if sample is None:
-            raise ValueError("Invalid value for `sample`, must not be `None`")  # noqa: E501
-
-        self._sample = sample
diff --git a/minipf/models/isd200_focal_length_model.py b/minipf/models/isd200_focal_length_model.py
deleted file mode 100644
index 01bcf312b1e85bd1bf7bb1160674d115ca0b6223..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_focal_length_model.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class ISD200FocalLengthModel(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, key: str=None, focal_length: float=None, focal_epsilon: float=None):  # noqa: E501
-        """ISD200FocalLengthModel - a model defined in OpenAPI
-
-        :param key: The key of this ISD200FocalLengthModel.  # noqa: E501
-        :type key: str
-        :param focal_length: The focal_length of this ISD200FocalLengthModel.  # noqa: E501
-        :type focal_length: float
-        :param focal_epsilon: The focal_epsilon of this ISD200FocalLengthModel.  # noqa: E501
-        :type focal_epsilon: float
-        """
-        self.openapi_types = {
-            'key': str,
-            'focal_length': float,
-            'focal_epsilon': float
-        }
-
-        self.attribute_map = {
-            'key': 'key',
-            'focal_length': 'focal_length',
-            'focal_epsilon': 'focal_epsilon'
-        }
-
-        self._key = key
-        self._focal_length = focal_length
-        self._focal_epsilon = focal_epsilon
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200FocalLengthModel':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_focal_length_model of this ISD200FocalLengthModel.  # noqa: E501
-        :rtype: ISD200FocalLengthModel
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def key(self) -> str:
-        """Gets the key of this ISD200FocalLengthModel.
-
-        A key to get information about time/temp dependent focal length models  # noqa: E501
-
-        :return: The key of this ISD200FocalLengthModel.
-        :rtype: str
-        """
-        return self._key
-
-    @key.setter
-    def key(self, key: str):
-        """Sets the key of this ISD200FocalLengthModel.
-
-        A key to get information about time/temp dependent focal length models  # noqa: E501
-
-        :param key: The key of this ISD200FocalLengthModel.
-        :type key: str
-        """
-
-        self._key = key
-
-    @property
-    def focal_length(self) -> float:
-        """Gets the focal_length of this ISD200FocalLengthModel.
-
-        The focal length in mm  # noqa: E501
-
-        :return: The focal_length of this ISD200FocalLengthModel.
-        :rtype: float
-        """
-        return self._focal_length
-
-    @focal_length.setter
-    def focal_length(self, focal_length: float):
-        """Sets the focal_length of this ISD200FocalLengthModel.
-
-        The focal length in mm  # noqa: E501
-
-        :param focal_length: The focal_length of this ISD200FocalLengthModel.
-        :type focal_length: float
-        """
-        if focal_length is None:
-            raise ValueError("Invalid value for `focal_length`, must not be `None`")  # noqa: E501
-
-        self._focal_length = focal_length
-
-    @property
-    def focal_epsilon(self) -> float:
-        """Gets the focal_epsilon of this ISD200FocalLengthModel.
-
-        The uncertainty of the focal length in mm  # noqa: E501
-
-        :return: The focal_epsilon of this ISD200FocalLengthModel.
-        :rtype: float
-        """
-        return self._focal_epsilon
-
-    @focal_epsilon.setter
-    def focal_epsilon(self, focal_epsilon: float):
-        """Sets the focal_epsilon of this ISD200FocalLengthModel.
-
-        The uncertainty of the focal length in mm  # noqa: E501
-
-        :param focal_epsilon: The focal_epsilon of this ISD200FocalLengthModel.
-        :type focal_epsilon: float
-        """
-
-        self._focal_epsilon = focal_epsilon
diff --git a/minipf/models/isd200_radii.py b/minipf/models/isd200_radii.py
deleted file mode 100644
index c7bb518e3a6406dc10fb01dc50ae7d5a817613a7..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_radii.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class ISD200Radii(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, semimajor: float=None, semiminor: float=None, unit: str=None):  # noqa: E501
-        """ISD200Radii - a model defined in OpenAPI
-
-        :param semimajor: The semimajor of this ISD200Radii.  # noqa: E501
-        :type semimajor: float
-        :param semiminor: The semiminor of this ISD200Radii.  # noqa: E501
-        :type semiminor: float
-        :param unit: The unit of this ISD200Radii.  # noqa: E501
-        :type unit: str
-        """
-        self.openapi_types = {
-            'semimajor': float,
-            'semiminor': float,
-            'unit': str
-        }
-
-        self.attribute_map = {
-            'semimajor': 'semimajor',
-            'semiminor': 'semiminor',
-            'unit': 'unit'
-        }
-
-        self._semimajor = semimajor
-        self._semiminor = semiminor
-        self._unit = unit
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200Radii':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_radii of this ISD200Radii.  # noqa: E501
-        :rtype: ISD200Radii
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def semimajor(self) -> float:
-        """Gets the semimajor of this ISD200Radii.
-
-
-        :return: The semimajor of this ISD200Radii.
-        :rtype: float
-        """
-        return self._semimajor
-
-    @semimajor.setter
-    def semimajor(self, semimajor: float):
-        """Sets the semimajor of this ISD200Radii.
-
-
-        :param semimajor: The semimajor of this ISD200Radii.
-        :type semimajor: float
-        """
-        if semimajor is None:
-            raise ValueError("Invalid value for `semimajor`, must not be `None`")  # noqa: E501
-
-        self._semimajor = semimajor
-
-    @property
-    def semiminor(self) -> float:
-        """Gets the semiminor of this ISD200Radii.
-
-
-        :return: The semiminor of this ISD200Radii.
-        :rtype: float
-        """
-        return self._semiminor
-
-    @semiminor.setter
-    def semiminor(self, semiminor: float):
-        """Sets the semiminor of this ISD200Radii.
-
-
-        :param semiminor: The semiminor of this ISD200Radii.
-        :type semiminor: float
-        """
-
-        self._semiminor = semiminor
-
-    @property
-    def unit(self) -> str:
-        """Gets the unit of this ISD200Radii.
-
-
-        :return: The unit of this ISD200Radii.
-        :rtype: str
-        """
-        return self._unit
-
-    @unit.setter
-    def unit(self, unit: str):
-        """Sets the unit of this ISD200Radii.
-
-
-        :param unit: The unit of this ISD200Radii.
-        :type unit: str
-        """
-        if unit is None:
-            raise ValueError("Invalid value for `unit`, must not be `None`")  # noqa: E501
-
-        self._unit = unit
diff --git a/minipf/models/isd200_reference_height.py b/minipf/models/isd200_reference_height.py
deleted file mode 100644
index d82034ddff931b2e8c09b9ff36fe1ac5bf0f3a03..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_reference_height.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class ISD200ReferenceHeight(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, minheight: float=None, maxheight: float=None, unit: str=None):  # noqa: E501
-        """ISD200ReferenceHeight - a model defined in OpenAPI
-
-        :param minheight: The minheight of this ISD200ReferenceHeight.  # noqa: E501
-        :type minheight: float
-        :param maxheight: The maxheight of this ISD200ReferenceHeight.  # noqa: E501
-        :type maxheight: float
-        :param unit: The unit of this ISD200ReferenceHeight.  # noqa: E501
-        :type unit: str
-        """
-        self.openapi_types = {
-            'minheight': float,
-            'maxheight': float,
-            'unit': str
-        }
-
-        self.attribute_map = {
-            'minheight': 'minheight',
-            'maxheight': 'maxheight',
-            'unit': 'unit'
-        }
-
-        self._minheight = minheight
-        self._maxheight = maxheight
-        self._unit = unit
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200ReferenceHeight':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_reference_height of this ISD200ReferenceHeight.  # noqa: E501
-        :rtype: ISD200ReferenceHeight
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def minheight(self) -> float:
-        """Gets the minheight of this ISD200ReferenceHeight.
-
-
-        :return: The minheight of this ISD200ReferenceHeight.
-        :rtype: float
-        """
-        return self._minheight
-
-    @minheight.setter
-    def minheight(self, minheight: float):
-        """Sets the minheight of this ISD200ReferenceHeight.
-
-
-        :param minheight: The minheight of this ISD200ReferenceHeight.
-        :type minheight: float
-        """
-        if minheight is None:
-            raise ValueError("Invalid value for `minheight`, must not be `None`")  # noqa: E501
-
-        self._minheight = minheight
-
-    @property
-    def maxheight(self) -> float:
-        """Gets the maxheight of this ISD200ReferenceHeight.
-
-
-        :return: The maxheight of this ISD200ReferenceHeight.
-        :rtype: float
-        """
-        return self._maxheight
-
-    @maxheight.setter
-    def maxheight(self, maxheight: float):
-        """Sets the maxheight of this ISD200ReferenceHeight.
-
-
-        :param maxheight: The maxheight of this ISD200ReferenceHeight.
-        :type maxheight: float
-        """
-        if maxheight is None:
-            raise ValueError("Invalid value for `maxheight`, must not be `None`")  # noqa: E501
-
-        self._maxheight = maxheight
-
-    @property
-    def unit(self) -> str:
-        """Gets the unit of this ISD200ReferenceHeight.
-
-        The unit that heights are provided in  # noqa: E501
-
-        :return: The unit of this ISD200ReferenceHeight.
-        :rtype: str
-        """
-        return self._unit
-
-    @unit.setter
-    def unit(self, unit: str):
-        """Sets the unit of this ISD200ReferenceHeight.
-
-        The unit that heights are provided in  # noqa: E501
-
-        :param unit: The unit of this ISD200ReferenceHeight.
-        :type unit: str
-        """
-        if unit is None:
-            raise ValueError("Invalid value for `unit`, must not be `None`")  # noqa: E501
-
-        self._unit = unit
diff --git a/minipf/models/isd200_sensor_position.py b/minipf/models/isd200_sensor_position.py
deleted file mode 100644
index 11d6146cd500f84435186b971f5109cc5d638c59..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_sensor_position.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf.models.xyz import XYZ  # noqa: F401,E501
-from minipf import util
-
-
-class ISD200SensorPosition(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, velocities: List[XYZ]=None, unit: str=None, positions: List[XYZ]=None):  # noqa: E501
-        """ISD200SensorPosition - a model defined in OpenAPI
-
-        :param velocities: The velocities of this ISD200SensorPosition.  # noqa: E501
-        :type velocities: List[XYZ]
-        :param unit: The unit of this ISD200SensorPosition.  # noqa: E501
-        :type unit: str
-        :param positions: The positions of this ISD200SensorPosition.  # noqa: E501
-        :type positions: List[XYZ]
-        """
-        self.openapi_types = {
-            'velocities': List[XYZ],
-            'unit': str,
-            'positions': List[XYZ]
-        }
-
-        self.attribute_map = {
-            'velocities': 'velocities',
-            'unit': 'unit',
-            'positions': 'positions'
-        }
-
-        self._velocities = velocities
-        self._unit = unit
-        self._positions = positions
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200SensorPosition':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_sensor_position of this ISD200SensorPosition.  # noqa: E501
-        :rtype: ISD200SensorPosition
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def velocities(self) -> List[XYZ]:
-        """Gets the velocities of this ISD200SensorPosition.
-
-
-        :return: The velocities of this ISD200SensorPosition.
-        :rtype: List[XYZ]
-        """
-        return self._velocities
-
-    @velocities.setter
-    def velocities(self, velocities: List[XYZ]):
-        """Sets the velocities of this ISD200SensorPosition.
-
-
-        :param velocities: The velocities of this ISD200SensorPosition.
-        :type velocities: List[XYZ]
-        """
-
-        self._velocities = velocities
-
-    @property
-    def unit(self) -> str:
-        """Gets the unit of this ISD200SensorPosition.
-
-
-        :return: The unit of this ISD200SensorPosition.
-        :rtype: str
-        """
-        return self._unit
-
-    @unit.setter
-    def unit(self, unit: str):
-        """Sets the unit of this ISD200SensorPosition.
-
-
-        :param unit: The unit of this ISD200SensorPosition.
-        :type unit: str
-        """
-
-        self._unit = unit
-
-    @property
-    def positions(self) -> List[XYZ]:
-        """Gets the positions of this ISD200SensorPosition.
-
-
-        :return: The positions of this ISD200SensorPosition.
-        :rtype: List[XYZ]
-        """
-        return self._positions
-
-    @positions.setter
-    def positions(self, positions: List[XYZ]):
-        """Sets the positions of this ISD200SensorPosition.
-
-
-        :param positions: The positions of this ISD200SensorPosition.
-        :type positions: List[XYZ]
-        """
-
-        self._positions = positions
diff --git a/minipf/models/isd200_sun_position.py b/minipf/models/isd200_sun_position.py
deleted file mode 100644
index 62e54dbc0413934aa73b1628654ca29d6588a3a3..0000000000000000000000000000000000000000
--- a/minipf/models/isd200_sun_position.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf.models.xyz import XYZ  # noqa: F401,E501
-from minipf import util
-
-
-class ISD200SunPosition(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, velocities: XYZ=None, unit: str=None, positions: XYZ=None):  # noqa: E501
-        """ISD200SunPosition - a model defined in OpenAPI
-
-        :param velocities: The velocities of this ISD200SunPosition.  # noqa: E501
-        :type velocities: XYZ
-        :param unit: The unit of this ISD200SunPosition.  # noqa: E501
-        :type unit: str
-        :param positions: The positions of this ISD200SunPosition.  # noqa: E501
-        :type positions: XYZ
-        """
-        self.openapi_types = {
-            'velocities': XYZ,
-            'unit': str,
-            'positions': XYZ
-        }
-
-        self.attribute_map = {
-            'velocities': 'velocities',
-            'unit': 'unit',
-            'positions': 'positions'
-        }
-
-        self._velocities = velocities
-        self._unit = unit
-        self._positions = positions
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'ISD200SunPosition':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The ISD200_sun_position of this ISD200SunPosition.  # noqa: E501
-        :rtype: ISD200SunPosition
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def velocities(self) -> XYZ:
-        """Gets the velocities of this ISD200SunPosition.
-
-
-        :return: The velocities of this ISD200SunPosition.
-        :rtype: XYZ
-        """
-        return self._velocities
-
-    @velocities.setter
-    def velocities(self, velocities: XYZ):
-        """Sets the velocities of this ISD200SunPosition.
-
-
-        :param velocities: The velocities of this ISD200SunPosition.
-        :type velocities: XYZ
-        """
-
-        self._velocities = velocities
-
-    @property
-    def unit(self) -> str:
-        """Gets the unit of this ISD200SunPosition.
-
-
-        :return: The unit of this ISD200SunPosition.
-        :rtype: str
-        """
-        return self._unit
-
-    @unit.setter
-    def unit(self, unit: str):
-        """Sets the unit of this ISD200SunPosition.
-
-
-        :param unit: The unit of this ISD200SunPosition.
-        :type unit: str
-        """
-
-        self._unit = unit
-
-    @property
-    def positions(self) -> XYZ:
-        """Gets the positions of this ISD200SunPosition.
-
-
-        :return: The positions of this ISD200SunPosition.
-        :rtype: XYZ
-        """
-        return self._positions
-
-    @positions.setter
-    def positions(self, positions: XYZ):
-        """Sets the positions of this ISD200SunPosition.
-
-
-        :param positions: The positions of this ISD200SunPosition.
-        :type positions: XYZ
-        """
-
-        self._positions = positions
diff --git a/minipf/models/optical_distortion.py b/minipf/models/optical_distortion.py
deleted file mode 100644
index 19c360c25a2ff93e81d684ed66cacedb454687d1..0000000000000000000000000000000000000000
--- a/minipf/models/optical_distortion.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf.models.optical_distortion_radial import OpticalDistortionRadial  # noqa: F401,E501
-from minipf.models.optical_distortion_transverse import OpticalDistortionTransverse  # noqa: F401,E501
-from minipf import util
-
-
-class OpticalDistortion(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, transverse: OpticalDistortionTransverse=None, radial: OpticalDistortionRadial=None):  # noqa: E501
-        """OpticalDistortion - a model defined in OpenAPI
-
-        :param transverse: The transverse of this OpticalDistortion.  # noqa: E501
-        :type transverse: OpticalDistortionTransverse
-        :param radial: The radial of this OpticalDistortion.  # noqa: E501
-        :type radial: OpticalDistortionRadial
-        """
-        self.openapi_types = {
-            'transverse': OpticalDistortionTransverse,
-            'radial': OpticalDistortionRadial
-        }
-
-        self.attribute_map = {
-            'transverse': 'transverse',
-            'radial': 'radial'
-        }
-
-        self._transverse = transverse
-        self._radial = radial
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'OpticalDistortion':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The optical_distortion of this OpticalDistortion.  # noqa: E501
-        :rtype: OpticalDistortion
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def transverse(self) -> OpticalDistortionTransverse:
-        """Gets the transverse of this OpticalDistortion.
-
-
-        :return: The transverse of this OpticalDistortion.
-        :rtype: OpticalDistortionTransverse
-        """
-        return self._transverse
-
-    @transverse.setter
-    def transverse(self, transverse: OpticalDistortionTransverse):
-        """Sets the transverse of this OpticalDistortion.
-
-
-        :param transverse: The transverse of this OpticalDistortion.
-        :type transverse: OpticalDistortionTransverse
-        """
-
-        self._transverse = transverse
-
-    @property
-    def radial(self) -> OpticalDistortionRadial:
-        """Gets the radial of this OpticalDistortion.
-
-
-        :return: The radial of this OpticalDistortion.
-        :rtype: OpticalDistortionRadial
-        """
-        return self._radial
-
-    @radial.setter
-    def radial(self, radial: OpticalDistortionRadial):
-        """Sets the radial of this OpticalDistortion.
-
-
-        :param radial: The radial of this OpticalDistortion.
-        :type radial: OpticalDistortionRadial
-        """
-
-        self._radial = radial
diff --git a/minipf/models/optical_distortion_radial.py b/minipf/models/optical_distortion_radial.py
deleted file mode 100644
index 0c419cd2f9698fbae12cb12d8fa2f1bc975e1136..0000000000000000000000000000000000000000
--- a/minipf/models/optical_distortion_radial.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class OpticalDistortionRadial(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, coefficients: List[float]=None):  # noqa: E501
-        """OpticalDistortionRadial - a model defined in OpenAPI
-
-        :param coefficients: The coefficients of this OpticalDistortionRadial.  # noqa: E501
-        :type coefficients: List[float]
-        """
-        self.openapi_types = {
-            'coefficients': List[float]
-        }
-
-        self.attribute_map = {
-            'coefficients': 'coefficients'
-        }
-
-        self._coefficients = coefficients
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'OpticalDistortionRadial':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The optical_distortion_radial of this OpticalDistortionRadial.  # noqa: E501
-        :rtype: OpticalDistortionRadial
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def coefficients(self) -> List[float]:
-        """Gets the coefficients of this OpticalDistortionRadial.
-
-
-        :return: The coefficients of this OpticalDistortionRadial.
-        :rtype: List[float]
-        """
-        return self._coefficients
-
-    @coefficients.setter
-    def coefficients(self, coefficients: List[float]):
-        """Sets the coefficients of this OpticalDistortionRadial.
-
-
-        :param coefficients: The coefficients of this OpticalDistortionRadial.
-        :type coefficients: List[float]
-        """
-
-        self._coefficients = coefficients
diff --git a/minipf/models/optical_distortion_transverse.py b/minipf/models/optical_distortion_transverse.py
deleted file mode 100644
index f8751535fc797498e36451d09ba14f27689c0cbc..0000000000000000000000000000000000000000
--- a/minipf/models/optical_distortion_transverse.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class OpticalDistortionTransverse(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, x: List[float]=None, y: List[float]=None):  # noqa: E501
-        """OpticalDistortionTransverse - a model defined in OpenAPI
-
-        :param x: The x of this OpticalDistortionTransverse.  # noqa: E501
-        :type x: List[float]
-        :param y: The y of this OpticalDistortionTransverse.  # noqa: E501
-        :type y: List[float]
-        """
-        self.openapi_types = {
-            'x': List[float],
-            'y': List[float]
-        }
-
-        self.attribute_map = {
-            'x': 'x',
-            'y': 'y'
-        }
-
-        self._x = x
-        self._y = y
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'OpticalDistortionTransverse':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The optical_distortion_transverse of this OpticalDistortionTransverse.  # noqa: E501
-        :rtype: OpticalDistortionTransverse
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def x(self) -> List[float]:
-        """Gets the x of this OpticalDistortionTransverse.
-
-
-        :return: The x of this OpticalDistortionTransverse.
-        :rtype: List[float]
-        """
-        return self._x
-
-    @x.setter
-    def x(self, x: List[float]):
-        """Sets the x of this OpticalDistortionTransverse.
-
-
-        :param x: The x of this OpticalDistortionTransverse.
-        :type x: List[float]
-        """
-
-        self._x = x
-
-    @property
-    def y(self) -> List[float]:
-        """Gets the y of this OpticalDistortionTransverse.
-
-
-        :return: The y of this OpticalDistortionTransverse.
-        :rtype: List[float]
-        """
-        return self._y
-
-    @y.setter
-    def y(self, y: List[float]):
-        """Sets the y of this OpticalDistortionTransverse.
-
-
-        :param y: The y of this OpticalDistortionTransverse.
-        :type y: List[float]
-        """
-
-        self._y = y
diff --git a/minipf/models/quaternion.py b/minipf/models/quaternion.py
deleted file mode 100644
index ea0cb62486ed182a00c0fa926c14606257d9c0ed..0000000000000000000000000000000000000000
--- a/minipf/models/quaternion.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class Quaternion(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self):  # noqa: E501
-        """Quaternion - a model defined in OpenAPI
-
-        """
-        self.openapi_types = {
-        }
-
-        self.attribute_map = {
-        }
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'Quaternion':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The Quaternion of this Quaternion.  # noqa: E501
-        :rtype: Quaternion
-        """
-        return util.deserialize_model(dikt, cls)
diff --git a/minipf/models/quaternions.py b/minipf/models/quaternions.py
deleted file mode 100644
index 57acf3c81b05a5bab0978cbe7e498e501248fce5..0000000000000000000000000000000000000000
--- a/minipf/models/quaternions.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class Quaternions(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, quaternions: List[List[float]]=None):  # noqa: E501
-        """Quaternions - a model defined in OpenAPI
-
-        :param quaternions: The quaternions of this Quaternions.  # noqa: E501
-        :type quaternions: List[List[float]]
-        """
-        self.openapi_types = {
-            'quaternions': List[List[float]]
-        }
-
-        self.attribute_map = {
-            'quaternions': 'quaternions'
-        }
-
-        self._quaternions = quaternions
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'Quaternions':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The Quaternions of this Quaternions.  # noqa: E501
-        :rtype: Quaternions
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def quaternions(self) -> List[List[float]]:
-        """Gets the quaternions of this Quaternions.
-
-        Orientation of the sensor provided in quaternions  # noqa: E501
-
-        :return: The quaternions of this Quaternions.
-        :rtype: List[List[float]]
-        """
-        return self._quaternions
-
-    @quaternions.setter
-    def quaternions(self, quaternions: List[List[float]]):
-        """Sets the quaternions of this Quaternions.
-
-        Orientation of the sensor provided in quaternions  # noqa: E501
-
-        :param quaternions: The quaternions of this Quaternions.
-        :type quaternions: List[List[float]]
-        """
-        if quaternions is None:
-            raise ValueError("Invalid value for `quaternions`, must not be `None`")  # noqa: E501
-
-        self._quaternions = quaternions
diff --git a/minipf/models/request_isd.py b/minipf/models/request_isd.py
deleted file mode 100644
index e48d088fcec9ad75bdfc86902f76f4c68b50f086..0000000000000000000000000000000000000000
--- a/minipf/models/request_isd.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class RequestISD(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self, label: str=None):  # noqa: E501
-        """RequestISD - a model defined in OpenAPI
-
-        :param label: The label of this RequestISD.  # noqa: E501
-        :type label: str
-        """
-        self.openapi_types = {
-            'label': str
-        }
-
-        self.attribute_map = {
-            'label': 'label'
-        }
-
-        self._label = label
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'RequestISD':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The request_ISD of this RequestISD.  # noqa: E501
-        :rtype: RequestISD
-        """
-        return util.deserialize_model(dikt, cls)
-
-    @property
-    def label(self) -> str:
-        """Gets the label of this RequestISD.
-
-
-        :return: The label of this RequestISD.
-        :rtype: str
-        """
-        return self._label
-
-    @label.setter
-    def label(self, label: str):
-        """Sets the label of this RequestISD.
-
-
-        :param label: The label of this RequestISD.
-        :type label: str
-        """
-
-        self._label = label
diff --git a/minipf/models/xyz.py b/minipf/models/xyz.py
deleted file mode 100644
index 7e18041da6f3b85e401d868ece1d052bb35b00ac..0000000000000000000000000000000000000000
--- a/minipf/models/xyz.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-from datetime import date, datetime  # noqa: F401
-
-from typing import List, Dict  # noqa: F401
-
-from minipf.models.base_model_ import Model
-from minipf import util
-
-
-class XYZ(Model):
-    """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
-
-    Do not edit the class manually.
-    """
-
-    def __init__(self):  # noqa: E501
-        """XYZ - a model defined in OpenAPI
-
-        """
-        self.openapi_types = {
-        }
-
-        self.attribute_map = {
-        }
-
-    @classmethod
-    def from_dict(cls, dikt) -> 'XYZ':
-        """Returns the dict as a model
-
-        :param dikt: A dict.
-        :type: dict
-        :return: The XYZ of this XYZ.  # noqa: E501
-        :rtype: XYZ
-        """
-        return util.deserialize_model(dikt, cls)
diff --git a/minipf/util.py b/minipf/util.py
deleted file mode 100644
index 75e234570cf092ab76a88b0dc8febc998a8963d8..0000000000000000000000000000000000000000
--- a/minipf/util.py
+++ /dev/null
@@ -1,215 +0,0 @@
-import datetime
-
-import os
-import six
-import typing
-import numpy as np
-from glob import glob
-from os import path
-from itertools import groupby, filterfalse
-from minipf import config
-
-
-
-def _deserialize(data, klass):
-    """Deserializes dict, list, str into an object.
-
-    :param data: dict, list or str.
-    :param klass: class literal, or string of class name.
-
-    :return: object.
-    """
-    if data is None:
-        return None
-    if klass in six.integer_types or klass in (float, str, bool):
-        return _deserialize_primitive(data, klass)
-    elif klass == object:
-        return _deserialize_object(data)
-    elif klass == datetime.date:
-        return deserialize_date(data)
-    elif klass == datetime.datetime:
-        return deserialize_datetime(data)
-    elif type(klass) == typing._GenericAlias:
-        if klass.__origin__ == list:
-            return _deserialize_list(data, klass.__args__[0])
-        if klass.__origin__ == dict:
-            return _deserialize_dict(data, klass.__args__[1])
-    else:
-        return deserialize_model(data, klass)
-
-
-def _deserialize_primitive(data, klass):
-    """Deserializes to primitive type.
-
-    :param data: data to deserialize.
-    :param klass: class literal.
-
-    :return: int, long, float, str, bool.
-    :rtype: int | long | float | str | bool
-    """
-    try:
-        value = klass(data)
-    except UnicodeEncodeError:
-        value = six.u(data)
-    except TypeError:
-        value = data
-    return value
-
-
-def _deserialize_object(value):
-    """Return an original value.
-
-    :return: object.
-    """
-    return value
-
-
-def deserialize_date(string):
-    """Deserializes string to date.
-
-    :param string: str.
-    :type string: str
-    :return: date.
-    :rtype: date
-    """
-    try:
-        from dateutil.parser import parse
-        return parse(string).date()
-    except ImportError:
-        return string
-
-
-def deserialize_datetime(string):
-    """Deserializes string to datetime.
-
-    The string should be in iso8601 datetime format.
-
-    :param string: str.
-    :type string: str
-    :return: datetime.
-    :rtype: datetime
-    """
-    try:
-        from dateutil.parser import parse
-        return parse(string)
-    except ImportError:
-        return string
-
-
-def deserialize_model(data, klass):
-    """Deserializes list or dict to model.
-
-    :param data: dict, list.
-    :type data: dict | list
-    :param klass: class literal.
-    :return: model object.
-    """
-    instance = klass()
-
-    if not instance.openapi_types:
-        return data
-
-    for attr, attr_type in six.iteritems(instance.openapi_types):
-        if data is not None \
-                and instance.attribute_map[attr] in data \
-                and isinstance(data, (list, dict)):
-            value = data[instance.attribute_map[attr]]
-            setattr(instance, attr, _deserialize(value, attr_type))
-
-    return instance
-
-
-def _deserialize_list(data, boxed_type):
-    """Deserializes a list and its elements.
-
-    :param data: list to deserialize.
-    :type data: list
-    :param boxed_type: class literal.
-
-    :return: deserialized list.
-    :rtype: list
-    """
-    return [_deserialize(sub_data, boxed_type)
-            for sub_data in data]
-
-
-def _deserialize_dict(data, boxed_type):
-    """Deserializes a dict and its elements.
-
-    :param data: dict to deserialize.
-    :type data: dict
-    :param boxed_type: class literal.
-
-    :return: deserialized dict.
-    :rtype: dict
-    """
-    return {k: _deserialize(v, boxed_type)
-            for k, v in six.iteritems(data)}
-
-
-def get_metakernels(spice_dir=config.spice_root, missions=set(), years=set(), versions=set()):
-    """
-    Given a root directory, get any subdirectory containing metakernels,
-    assume spice directory structure.
-
-    Mostly doing filtering here, might be worth using Pandas?
-    """
-    if not missions or missions == "all":
-        missions = set()
-    if not years or years == "all":
-        years = set()
-    if not versions or versions == "all":
-        versions = set()
-
-    if isinstance(missions, str):
-        missions = {missions}
-
-    if isinstance(years, str) or isinstance(years, int):
-        years = {str(years)}
-    else:
-        years = {str(year) for year in years}
-
-    avail = {
-        'count': 0,
-        'data': []
-    }
-
-    mission_dirs = list(filter(os.path.isdir, glob(os.path.join(spice_dir, '*'))))
-
-    for md in mission_dirs:
-        # Assuming spice root has the same name as the original on NAIF website"
-        mission = os.path.basename(md).split('-')[0]
-        if missions and mission not in missions:
-            continue
-
-        metakernel_keys = ['mission', 'year', 'version', 'path']
-
-        # recursive glob to make metakernel search more robust to subtle directory structure differences
-        metakernel_paths = sorted(glob(os.path.join(md, '**','*.tm'), recursive=True))
-
-        metakernels = [dict(zip(metakernel_keys, [mission]+path.splitext(path.basename(k))[0].split('_')[1:3] + [k])) for k in metakernel_paths]
-
-        # naive filter, do we really need anything else?
-        if years:
-            metakernels = list(filter(lambda x:x['year'] in years, metakernels))
-        if versions:
-            if versions == 'latest':
-                latest = []
-                # Panda's groupby is overrated
-                for k, g in groupby(metakernels, lambda x:x['year']):
-                    items = list(g)
-                    latest.append(max(items, key=lambda x:x['version']))
-                metakernels = latest
-            else:
-                metakernels = list(filter(lambda x:x['version'] in versions, metakernels))
-
-        avail['data'].extend(metakernels)
-
-    avail['count'] = len(avail['data'])
-    if not avail:
-        avail = {
-            'count' : 0,
-            'data' : 'ERROR: NONE OF {} ARE VALID MISSIONS'.format(missions)
-        }
-
-    return avail
diff --git a/setup.py b/setup.py
index 167fa74b5ddaf081f49564103d8c0e0e394cc76d..621a86a20f5353c2f98297758b5d93867ea0cc0c 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 import sys
 from setuptools import setup, find_packages
 
-NAME = "minipf"
+NAME = "Ale"
 VERSION = "0.0.1"
 
 # To install the library, run the following
@@ -16,12 +16,12 @@ VERSION = "0.0.1"
 setup(
     name=NAME,
     version=VERSION,
-    description="Barebones version of pfeffernusse",
+    description="Abstraction Layer for Ephemerides",
     author_email="jlaura@usgs.gov",
     url="",
-    keywords=["Pfeffernusse"],
+    keywords=[""],
     packages=find_packages(),
     long_description="""\
-    A SpiceAPI for extracting NAIF Spice Data
+    An Abstraction library for reading, writing and computing ephemeris data
     """
 )
diff --git a/src/eal.cpp b/src/ale.cpp
similarity index 99%
rename from src/eal.cpp
rename to src/ale.cpp
index 490e5ec627fe2d3c55c6a73f9d17deab79fce4c1..d522513200c413725556088559453f9ac590ecc0 100644
--- a/src/eal.cpp
+++ b/src/ale.cpp
@@ -1,4 +1,4 @@
-#include "eal.h"
+#include "ale.h"
 
 #include <json.hpp>
 
@@ -16,7 +16,7 @@
 using json = nlohmann::json;
 using namespace std;
 
-namespace eal {
+namespace ale {
 
   // Parsing the JSON
   json constructStateFromIsd(const string positionRotationData) {
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index 9271b2cb532ca19cc93e4295c1833e3689ef227c..0000000000000000000000000000000000000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-
-# collect all of the test sources
-file(GLOB test_source "${CMAKE_SOURCE_DIR}/tests/*.cpp")
-
-# setup test executable
-add_executable(runEALTests ${test_source})
-target_link_libraries(runEALTests eal ${GSL_LIBRARIES} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread)
-
-target_include_directories(runEALTests
-                           PRIVATE
-                           ${GSL_INCLUDE_DIRS}
-                           PUBLIC
-                           ${EAL_INCLUDE_DIRS})
-
-
-gtest_discover_tests(runEALTests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
diff --git a/tests/EalTest.cpp b/tests/ctests/AleTest.cpp
similarity index 72%
rename from tests/EalTest.cpp
rename to tests/ctests/AleTest.cpp
index 9f7c83f311c36634281684a678a5bb1bdc1a284b..465f6592ac99cf4da5a8904496ed2bfe6e0b8432 100644
--- a/tests/EalTest.cpp
+++ b/tests/ctests/AleTest.cpp
@@ -1,6 +1,6 @@
 #include "gtest/gtest.h"
 
-#include "eal.h"
+#include "ale.h"
 
 #include <stdexcept>
 #include <gsl/gsl_interp.h>
@@ -14,7 +14,7 @@ TEST(PositionInterpTest, LinearInterp) {
                                  {  9,  4,  1,  0,  1,  4},
                                  {-27, -8, -1,  0,  1,  8}};
 
-  vector<double> coordinate = eal::getPosition(data, times, -1.5, eal::linear);
+  vector<double> coordinate = ale::getPosition(data, times, -1.5, ale::linear);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(-1.5, coordinate[0]);
@@ -28,7 +28,7 @@ TEST(PositionInterpTest, SplineInterp) {
                                  {0, 1, 2, 3},
                                  {0, 2, 1, 0}};
 
-  vector<double> coordinate = eal::getPosition(data, times, 0.5, eal::spline);
+  vector<double> coordinate = ale::getPosition(data, times, 0.5, ale::spline);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(0,      coordinate[0]);
@@ -43,7 +43,7 @@ TEST(PositionInterpTest, FourCoordinates) {
                                  {-27, -8, -1,  0,  1,  8},
                                  { 25,  0, -5, 25,  3,  6}};
 
-  EXPECT_THROW(eal::getPosition(data, times, 0.0, eal::linear),
+  EXPECT_THROW(ale::getPosition(data, times, 0.0, ale::linear),
                invalid_argument);
 }
 
@@ -52,20 +52,20 @@ TEST(LinearInterpTest, ExampleInterpolation) {
   vector<double> times = {0,  1,  2, 3};
   vector<double> data = {0, 2, 1, 0};
 
-  EXPECT_DOUBLE_EQ(0.0, eal::interpolate(data, times, 0.0, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(1.0, eal::interpolate(data, times, 0.5, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(2.0, eal::interpolate(data, times, 1.0, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(1.5, eal::interpolate(data, times, 1.5, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(1.0, eal::interpolate(data, times, 2.0, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(0.5, eal::interpolate(data, times, 2.5, eal::linear, 0));
-  EXPECT_DOUBLE_EQ(0.0, eal::interpolate(data, times, 3.0, eal::linear, 0));
+  EXPECT_DOUBLE_EQ(0.0, ale::interpolate(data, times, 0.0, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(1.0, ale::interpolate(data, times, 0.5, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(2.0, ale::interpolate(data, times, 1.0, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(1.5, ale::interpolate(data, times, 1.5, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(1.0, ale::interpolate(data, times, 2.0, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(0.5, ale::interpolate(data, times, 2.5, ale::linear, 0));
+  EXPECT_DOUBLE_EQ(0.0, ale::interpolate(data, times, 3.0, ale::linear, 0));
 }
 
 TEST(LinearInterpTest, NoPoints) {
   vector<double> times = {};
   vector<double> data = {};
 
-  EXPECT_THROW(eal::interpolate(data, times, 0.0, eal::linear, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 0.0, ale::linear, 0),
                invalid_argument);
 }
 
@@ -73,7 +73,7 @@ TEST(LinearInterpTest, DifferentCounts) {
   vector<double> times = { -3, -2, -1,  0,  2};
   vector<double> data = { -3, -2, 1,  2};
 
-  EXPECT_THROW(eal::interpolate(data, times, 0.0, eal::linear, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 0.0, ale::linear, 0),
                invalid_argument);
 }
 
@@ -81,9 +81,9 @@ TEST(LinearInterpTest, Extrapolate) {
   vector<double> times = {0,  1,  2, 3};
   vector<double> data = {0, 2, 1, 0};
 
-  EXPECT_THROW(eal::interpolate(data, times, -1.0, eal::linear, 0),
+  EXPECT_THROW(ale::interpolate(data, times, -1.0, ale::linear, 0),
                invalid_argument);
-  EXPECT_THROW(eal::interpolate(data, times, 4.0, eal::linear, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 4.0, ale::linear, 0),
                invalid_argument);
 }
 
@@ -98,23 +98,23 @@ TEST(SplineInterpTest, ExampleInterpolation) {
 
   // The spline interpolation is only ~1e-10 so we have to define a tolerance
   double tolerance = 1e-10;
-  EXPECT_NEAR(0.0, eal::interpolate(data, times, 0.0, eal::spline, 0), tolerance);
+  EXPECT_NEAR(0.0, ale::interpolate(data, times, 0.0, ale::spline, 0), tolerance);
   EXPECT_NEAR(2.8 * 0.5 - 0.8 * 0.125,
-              eal::interpolate(data, times, 0.5, eal::spline, 0), tolerance);
-  EXPECT_NEAR(2.0, eal::interpolate(data, times, 1.0, eal::spline, 0), tolerance);
+              ale::interpolate(data, times, 0.5, ale::spline, 0), tolerance);
+  EXPECT_NEAR(2.0, ale::interpolate(data, times, 1.0, ale::spline, 0), tolerance);
   EXPECT_NEAR(3.375 - 5.4 * 2.25 + 8.2 * 1.5 - 1.8,
-              eal::interpolate(data, times, 1.5, eal::spline, 0), tolerance);
-  EXPECT_NEAR(1.0, eal::interpolate(data, times, 2.0, eal::spline, 0), tolerance);
+              ale::interpolate(data, times, 1.5, ale::spline, 0), tolerance);
+  EXPECT_NEAR(1.0, ale::interpolate(data, times, 2.0, ale::spline, 0), tolerance);
   EXPECT_NEAR(-0.2 * 15.625 + 1.8 * 6.25 - 6.2 * 2.5 + 7.8,
-              eal::interpolate(data, times, 2.5, eal::spline, 0), tolerance);
-  EXPECT_NEAR(0.0, eal::interpolate(data, times, 3.0, eal::spline, 0), tolerance);
+              ale::interpolate(data, times, 2.5, ale::spline, 0), tolerance);
+  EXPECT_NEAR(0.0, ale::interpolate(data, times, 3.0, ale::spline, 0), tolerance);
 }
 
 TEST(SplineInterpTest, NoPoints) {
   vector<double> times = {};
   vector<double> data = {};
 
-  EXPECT_THROW(eal::interpolate(data, times, 0.0, eal::spline, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 0.0, ale::spline, 0),
                invalid_argument);
 }
 
@@ -122,7 +122,7 @@ TEST(SplineInterpTest, DifferentCounts) {
   vector<double> times = { -3, -2, -1,  0,  2};
   vector<double> data = { -3, -2, 1,  2};
 
-  EXPECT_THROW(eal::interpolate(data, times, 0.0, eal::spline, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 0.0, ale::spline, 0),
                invalid_argument);
 }
 
@@ -130,31 +130,31 @@ TEST(SplineInterpTest, Extrapolate) {
   vector<double> times = {0,  1,  2, 3};
   vector<double> data = {0, 2, 1, 0};
 
-  EXPECT_THROW(eal::interpolate(data, times, -1.0, eal::spline, 0),
+  EXPECT_THROW(ale::interpolate(data, times, -1.0, ale::spline, 0),
                invalid_argument);
-  EXPECT_THROW(eal::interpolate(data, times, 4.0, eal::spline, 0),
+  EXPECT_THROW(ale::interpolate(data, times, 4.0, ale::spline, 0),
                invalid_argument);
 }
 
 TEST(PolynomialTest, Evaluate) {
   vector<double> coeffs = {1.0, 2.0, 3.0}; // 1 + 2x + 3x^2
-  EXPECT_EQ(2.0, eal::evaluatePolynomial(coeffs, -1, 0));
+  EXPECT_EQ(2.0, ale::evaluatePolynomial(coeffs, -1, 0));
 }
 
 TEST(PolynomialTest, Derivatives) {
   vector<double> coeffs = {1.0, 2.0, 3.0}; // 1 + 2x + 3x^2
-  EXPECT_EQ(-4.0, eal::evaluatePolynomial(coeffs, -1, 1));
-  EXPECT_EQ(6.0, eal::evaluatePolynomial(coeffs, -1, 2));
+  EXPECT_EQ(-4.0, ale::evaluatePolynomial(coeffs, -1, 1));
+  EXPECT_EQ(6.0, ale::evaluatePolynomial(coeffs, -1, 2));
 }
 
 TEST(PolynomialTest, EmptyCoeffs) {
   vector<double> coeffs = {};
-  EXPECT_THROW(eal::evaluatePolynomial(coeffs, -1, 1), invalid_argument);
+  EXPECT_THROW(ale::evaluatePolynomial(coeffs, -1, 1), invalid_argument);
 }
 
 TEST(PolynomialTest, BadDerivative) {
   vector<double> coeffs = {1.0, 2.0, 3.0};
-  EXPECT_THROW(eal::evaluatePolynomial(coeffs, -1, -1), invalid_argument);
+  EXPECT_THROW(ale::evaluatePolynomial(coeffs, -1, -1), invalid_argument);
 }
 
 TEST(PoisitionCoeffTest, SecondOrderPolynomial) {
@@ -163,7 +163,7 @@ TEST(PoisitionCoeffTest, SecondOrderPolynomial) {
                                    {1.0, 3.0, 2.0},
                                    {3.0, 2.0, 1.0}};
 
-  vector<double> coordinate = eal::getPosition(coeffs, time);
+  vector<double> coordinate = ale::getPosition(coeffs, time);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(17.0, coordinate[0]);
@@ -177,7 +177,7 @@ TEST(PoisitionCoeffTest, DifferentPolynomialDegrees) {
                                    {1.0, 2.0},
                                    {1.0, 2.0, 3.0}};
 
-  vector<double> coordinate = eal::getPosition(coeffs, time);
+  vector<double> coordinate = ale::getPosition(coeffs, time);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(1.0,  coordinate[0]);
@@ -191,7 +191,7 @@ TEST(PoisitionCoeffTest, NegativeInputs) {
                                    {1.0, -2.0, 3.0},
                                    {-1.0, 2.0, -3.0}};
 
-  vector<double> coordinate = eal::getPosition(coeffs, time);
+  vector<double> coordinate = ale::getPosition(coeffs, time);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(-9.0,  coordinate[0]);
@@ -205,7 +205,7 @@ TEST(PoisitionCoeffTest, InvalidInput) {
   vector<vector<double>> invalid_coeffs_sizes = {{3.0, 2.0, 1.0},
                                                  {1.0, 2.0, 3.0}};
 
-  EXPECT_THROW(eal::getPosition(invalid_coeffs_sizes, valid_time), invalid_argument);
+  EXPECT_THROW(ale::getPosition(invalid_coeffs_sizes, valid_time), invalid_argument);
 }
 
 
@@ -215,7 +215,7 @@ TEST(VelocityCoeffTest, SecondOrderPolynomial) {
                                    {1.0, 3.0, 2.0},
                                    {3.0, 2.0, 1.0}};
 
-  vector<double> coordinate = eal::getVelocity(coeffs, time);
+  vector<double> coordinate = ale::getVelocity(coeffs, time);
 
   ASSERT_EQ(3, coordinate.size());
   EXPECT_DOUBLE_EQ(14.0, coordinate[0]);
@@ -229,7 +229,7 @@ TEST(VelocityCoeffTest, InvalidInput) {
   vector<vector<double>> invalid_coeffs_sizes = {{3.0, 2.0, 1.0},
                                                  {1.0, 2.0, 3.0}};
 
-  EXPECT_THROW(eal::getVelocity(invalid_coeffs_sizes, valid_time), invalid_argument);
+  EXPECT_THROW(ale::getVelocity(invalid_coeffs_sizes, valid_time), invalid_argument);
 }
 
 
@@ -237,7 +237,7 @@ TEST(LinearInterpTest, ExmapleGetRotation) {
   // simple test, only checks if API hit correctly and output is normalized
   vector<double> times = {0,  1,  2, 3};
   vector<vector<double>> rots({{1,1,1,1}, {0,0,0,0}, {1,1,1,1}, {0,0,0,0}});
-  vector<double> r = eal::getRotation(rots, times, 2, eal::linear);
+  vector<double> r = ale::getRotation(rots, times, 2, ale::linear);
 
   ASSERT_NEAR(0.707107,  r[0], 0.000001);
   EXPECT_DOUBLE_EQ(0,  r[1]);
@@ -250,6 +250,6 @@ TEST(LinearInterpTest, GetRotationDifferentCounts) {
   // incorrect params
   vector<double> times = {0, 1, 2};
   vector<vector<double>> rots({{1,1,1,1}, {0,0,0,0}, {1,1,1,1}, {0,0,0,0}});
-  EXPECT_THROW(eal::getRotation(rots, times, 2, eal::linear), invalid_argument);
+  EXPECT_THROW(ale::getRotation(rots, times, 2, ale::linear), invalid_argument);
 
 }
diff --git a/tests/ctests/CMakeLists.txt b/tests/ctests/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..07973f94cf86251f7b28f417fd48a3601b83e36b
--- /dev/null
+++ b/tests/ctests/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.10)
+
+# collect all of the test sources
+file(GLOB test_source "${CMAKE_SOURCE_DIR}/tests/ctests/*.cpp")
+
+# setup test executable
+add_executable(runALETests ${test_source})
+target_link_libraries(runALETests ale ${GSL_LIBRARIES} ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES} pthread)
+
+target_include_directories(runALETests
+                           PRIVATE
+                           ${GSL_INCLUDE_DIRS}
+                           PUBLIC
+                           ${ALE_INCLUDE_DIRS})
+
+
+gtest_discover_tests(runALETests WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests)
diff --git a/tests/TestMain.cpp b/tests/ctests/TestMain.cpp
similarity index 100%
rename from tests/TestMain.cpp
rename to tests/ctests/TestMain.cpp
diff --git a/tests/pytests/conftest.py b/tests/pytests/conftest.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3a3b1d930eabb848bd17c7b03f29460b9500093
--- /dev/null
+++ b/tests/pytests/conftest.py
@@ -0,0 +1,28 @@
+import numpy as np
+
+class SimpleSpice():
+    def scs2e(self, *args):
+        return 0.1
+    def bods2c(self, x):
+        return -12345
+    def gdpool(self, key, x, length):
+        return np.ones(length)
+    def bodvrd(self, key, x, length):
+        return (3, np.ones(length,))
+    def spkpos(self, *args):
+        return (np.ones(3), None)
+    def spkezr(self, *args):
+        return (np.ones(6), None)
+    def furnsh(self, *args):
+        return
+    def unload(self, *args):
+        return
+    def pxform(self, *args):
+        return
+    def m2q(self, *args):
+        return np.asarray([1,2,3,4])
+    def bodn2c(self, *args):
+        return "SPACE"
+
+def get_mockkernels(self, *args):
+    return "some_metakernel"
diff --git a/tests/pytests/test_lro_drivers.py b/tests/pytests/test_lro_drivers.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e0bd6dae3c09d148edc39a96b93679406378825
--- /dev/null
+++ b/tests/pytests/test_lro_drivers.py
@@ -0,0 +1,118 @@
+from collections import namedtuple
+from unittest import mock
+
+import pytest
+
+import ale
+from ale.drivers import lro_driver, base, distortion
+from ale.drivers.lro_driver import LRO_LROC
+from ale import util
+
+# 'Mock' the spice module where it is imported
+from conftest import SimpleSpice, get_mockkernels
+
+simplespice = SimpleSpice()
+base.spice = simplespice
+lro_driver.spice = simplespice
+distortion.spice = simplespice
+
+LRO_LROC.metakernel = get_mockkernels
+
+@pytest.fixture
+def lro_lroclabel():
+    return """
+        PDS_VERSION_ID                     = PDS3
+
+        /*FILE CHARACTERISTICS*/
+        RECORD_TYPE                        = FIXED_LENGTH
+        RECORD_BYTES                       = 5064
+        FILE_RECORDS                       = 13313
+        LABEL_RECORDS                      = 1
+        ^IMAGE                             = 2
+
+        /*DATA IDENTIFICATION*/
+        DATA_SET_ID                        = "LRO-L-LROC-2-EDR-V1.0"
+        ORIGINAL_PRODUCT_ID                = nacl0002fc60
+        PRODUCT_ID                         = M128963531LE
+        MISSION_NAME                       = "LUNAR RECONNAISSANCE ORBITER"
+        MISSION_PHASE_NAME                 = "NOMINAL MISSION"
+        INSTRUMENT_HOST_NAME               = "LUNAR RECONNAISSANCE ORBITER"
+        INSTRUMENT_HOST_ID                 = LRO
+        INSTRUMENT_NAME                    = "LUNAR RECONNAISSANCE ORBITER CAMERA"
+        INSTRUMENT_ID                      = LROC
+        LRO:PREROLL_TIME                   = 2010-05-20T02:57:44.373
+        START_TIME                         = 2010-05-20T02:57:44.720
+        STOP_TIME                          = 2010-05-20T02:57:49.235
+        LRO:SPACECRAFT_CLOCK_PREROLL_COUNT = "1/296017064:22937"
+        SPACECRAFT_CLOCK_START_COUNT       = "1/296017064:45694"
+        SPACECRAFT_CLOCK_STOP_COUNT        = "1/296017069:13866"
+        ORBIT_NUMBER                       = 4138
+        PRODUCER_ID                        = LRO_LROC_TEAM
+        PRODUCT_CREATION_TIME              = 2013-09-16T19:57:12
+        PRODUCER_INSTITUTION_NAME          = "ARIZONA STATE UNIVERSITY"
+        PRODUCT_TYPE                       = EDR
+        PRODUCT_VERSION_ID                 = "v1.8"
+        UPLOAD_ID                          = "SC_2010140_0000_A_V01.txt"
+
+        /*DATA DESCRIPTION*/
+        TARGET_NAME                        = "MOON"
+        RATIONALE_DESC                     = "TARGET OF OPPORTUNITY"
+        FRAME_ID                           = LEFT
+        DATA_QUALITY_ID                    = "0"
+        DATA_QUALITY_DESC                  = "The DATA_QUALITY_ID is set to an 8-bit
+           value that encodes the following data quality information for the
+           observation. For each bit  a value of 0 means FALSE and a value of 1 means
+           TRUE. More information about the data quality ID can be found in the LROC
+           EDR/CDR SIS, section 3.3 'Label and Header Descriptions'.
+               Bit 1: Temperature of focal plane array is out of bounds.
+               Bit 2: Threshold for saturated pixels is reached.
+               Bit 3: Threshold for under-saturated pixels is reached.
+               Bit 4: Observation is missing telemetry packets.
+               Bit 5: SPICE information is bad or missing.
+               Bit 6: Observation or housekeeping information is bad or missing.
+               Bit 7: Spare.
+               Bit 8: Spare."
+
+        /*ENVIRONMENT*/
+        LRO:TEMPERATURE_SCS                = 4.51 <degC>
+        LRO:TEMPERATURE_FPA                = 17.88 <degC>
+        LRO:TEMPERATURE_FPGA               = -12.33 <degC>
+        LRO:TEMPERATURE_TELESCOPE          = 5.91 <degC>
+        LRO:TEMPERATURE_SCS_RAW            = 2740
+        LRO:TEMPERATURE_FPA_RAW            = 2107
+        LRO:TEMPERATURE_FPGA_RAW           = 3418
+        LRO:TEMPERATURE_TELESCOPE_RAW      = 2675
+
+        /*IMAGING PARAMETERS*/
+        CROSSTRACK_SUMMING                 = 1
+        BANDWIDTH                          = 300 <nm>
+        CENTER_FILTER_WAVELENGTH           = 600 <nm>
+        LINE_EXPOSURE_DURATION             = 0.337600 <ms>
+        LRO:LINE_EXPOSURE_CODE             = 0
+        LRO:DAC_RESET_LEVEL                = 198
+        LRO:CHANNEL_A_OFFSET               = 60
+        LRO:CHANNEL_B_OFFSET               = 123
+        LRO:COMPAND_CODE                   = 3
+        LRO:LINE_CODE                      = 13
+        LRO:BTERM                          = (0,16,69,103,128)
+        LRO:MTERM                          = (0.5,0.25,0.125,0.0625,0.03125)
+        LRO:XTERM                          = (0,64,424,536,800)
+        LRO:COMPRESSION_FLAG               = 1
+        LRO:MODE                           = 7
+
+        /*DATA OBJECT*/
+        OBJECT                             = IMAGE
+            LINES                          = 13312
+            LINE_SAMPLES                   = 5064
+            SAMPLE_BITS                    = 8
+            SAMPLE_TYPE                    = LSB_INTEGER
+            UNIT                           = "RAW_INSTRUMENT_COUNT"
+            MD5_CHECKSUM                   = "0fe91f4b2e93083ee0093e7c8d05f3bc"
+        END_OBJECT                         = IMAGE
+        END
+        """
+
+def test_lro_creation(lro_lroclabel):
+    with LRO_LROC(lro_lroclabel) as m:
+        d = m.to_dict()
+        assert isinstance(d, dict)
diff --git a/tests/pytests/test_mdis_driver.py b/tests/pytests/test_mdis_driver.py
new file mode 100644
index 0000000000000000000000000000000000000000..1084934187cca9d42fe3e69bd1d02bac3c1541fb
--- /dev/null
+++ b/tests/pytests/test_mdis_driver.py
@@ -0,0 +1,250 @@
+from collections import namedtuple
+from unittest import mock
+
+import pytest
+
+import ale
+from ale.drivers import mdis_driver, base, distortion
+from ale.drivers.mdis_driver import Messenger
+
+
+# 'Mock' the spice module where it is imported
+from conftest import SimpleSpice, get_mockkernels
+
+simplespice = SimpleSpice()
+base.spice = simplespice
+mdis_driver.spice = simplespice
+distortion.spice = simplespice
+
+Messenger.metakernel = get_mockkernels
+
+@pytest.fixture
+def mdislabel():
+    return """
+PDS_VERSION_ID       = PDS3
+
+/*** FILE FORMAT ***/
+RECORD_TYPE          = FIXED_LENGTH
+RECORD_BYTES         = 2048
+FILE_RECORDS          = 1028
+LABEL_RECORDS         = 0004
+
+/*** POINTERS TO START BYTE OFFSET OF OBJECTS IN IMAGE FILE ***/
+^IMAGE                = 0005
+
+/*** GENERAL DATA DESCRIPTION PARAMETERS ***/
+MISSION_NAME         = "MESSENGER"
+INSTRUMENT_HOST_NAME = "MESSENGER"
+DATA_SET_ID          = "MESS-E/V/H-MDIS-2-EDR-RAWDATA-V1.0"
+DATA_QUALITY_ID      = "0000000000000000"
+PRODUCT_ID           = "EN0024934993M"
+PRODUCT_VERSION_ID   = "3"
+SOURCE_PRODUCT_ID    = ("0024934993_IM3WV")
+PRODUCER_INSTITUTION_NAME = "APPLIED COHERENT TECHNOLOGY CORPORATION"
+SOFTWARE_NAME        = "MDIS2EDR"
+SOFTWARE_VERSION_ID  = "1.0"
+MISSION_PHASE_NAME   = "EARTH CRUISE"
+TARGET_NAME          = "EARTH"
+SEQUENCE_NAME        = "05138_MLA_SUPP_1"
+OBSERVATION_ID       = "703"
+OBSERVATION_TYPE     = "N/A"
+SITE_ID              = "N/A"
+
+/*** TIME PARAMETERS ***/
+START_TIME           = 2005-05-18T20:24:10.515023
+STOP_TIME            = 2005-05-18T20:24:10.707023
+SPACECRAFT_CLOCK_START_COUNT = "1/0024934993:798000"
+SPACECRAFT_CLOCK_STOP_COUNT = "1/0024934993:990000"
+ORBIT_NUMBER         = "N/A"
+PRODUCT_CREATION_TIME = 2011-11-21T22:17:22
+
+/***  INSTRUMENT ENGINEERING PARAMETERS ***/
+INSTRUMENT_NAME      = "MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA"
+INSTRUMENT_ID        = "MDIS-NAC"
+FILTER_NAME          = "748 BP 53"
+FILTER_NUMBER        = "N/A"
+CENTER_FILTER_WAVELENGTH = 747.7 <NM>
+BANDWIDTH            = 52.6 <NM>
+EXPOSURE_DURATION    = 192 <MS>
+EXPOSURE_TYPE        = AUTO
+DETECTOR_TEMPERATURE = -42.55 <DEGC>
+FOCAL_PLANE_TEMPERATURE = -35.94 <DEGC>
+FILTER_TEMPERATURE   = "N/A"
+OPTICS_TEMPERATURE   = -37.36 <DEGC>
+
+/*** INSTRUMENT RAW PARAMETERS ***/
+MESS:MET_EXP         = 24934993
+MESS:IMG_ID_LSB      = "N/A"
+MESS:IMG_ID_MSB      = "N/A"
+MESS:ATT_CLOCK_COUNT = 24934991
+MESS:ATT_Q1          = 0.38073087
+MESS:ATT_Q2          = -0.50538123
+MESS:ATT_Q3          = 0.72235280
+MESS:ATT_Q4          = 0.27899864
+MESS:ATT_FLAG        = 7
+MESS:PIV_POS_MOTOR   = "N/A"
+MESS:PIV_GOAL        = 0
+MESS:PIV_POS         = -1
+MESS:PIV_READ        = 20740
+MESS:PIV_CAL         = -26758
+MESS:FW_GOAL         = 17376
+MESS:FW_POS          = 17420
+MESS:FW_READ         = 17420
+MESS:CCD_TEMP        = 1026
+MESS:CAM_T1          = 454
+MESS:CAM_T2          = 478
+MESS:EXPOSURE        = 192
+MESS:DPU_ID          = 0
+MESS:IMAGER          = 1
+MESS:SOURCE          = 0
+MESS:FPU_BIN         = 0
+MESS:COMP12_8        = 0
+MESS:COMP_ALG        = 2
+MESS:COMP_FST        = 1
+MESS:TIME_PLS        = 1
+MESS:LATCH_UP        = 0
+MESS:EXP_MODE        = 1
+MESS:PIV_STAT        = 3
+MESS:PIV_MPEN        = 0
+MESS:PIV_PV          = 1
+MESS:PIV_RV          = 1
+MESS:FW_PV           = 1
+MESS:FW_RV           = 1
+MESS:AEX_STAT        = 256
+MESS:AEX_STHR        = 0
+MESS:AEX_TGTB        = 2800
+MESS:AEX_BACB        = 240
+MESS:AEX_MAXE        = 714
+MESS:AEX_MINE        = 1
+MESS:DLNKPRIO        = 3
+MESS:WVLRATIO        = 4
+MESS:PIXELBIN        = 0
+MESS:SUBFRAME        = 0
+MESS:SUBF_X1         = 4
+MESS:SUBF_Y1         = 0
+MESS:SUBF_DX1        = 0
+MESS:SUBF_DY1        = 0
+MESS:SUBF_X2         = 4
+MESS:SUBF_Y2         = 0
+MESS:SUBF_DX2        = 0
+MESS:SUBF_DY2        = 0
+MESS:SUBF_X3         = 0
+MESS:SUBF_Y3         = 0
+MESS:SUBF_DX3        = 0
+MESS:SUBF_DY3        = 0
+MESS:SUBF_X4         = 0
+MESS:SUBF_Y4         = 0
+MESS:SUBF_DX4        = 0
+MESS:SUBF_DY4        = 0
+MESS:SUBF_X5         = 0
+MESS:SUBF_Y5         = 0
+MESS:SUBF_DX5        = 0
+MESS:SUBF_DY5        = 0
+MESS:CRITOPNV        = 0
+MESS:JAILBARS        = 0
+MESS:JB_X0           = 0
+MESS:JB_X1           = 0
+MESS:JB_SPACE        = 0
+
+/*** GEOMETRY INFORMATION ***/
+RIGHT_ASCENSION      = 285.95273 <DEG>
+DECLINATION          = 11.71507 <DEG>
+TWIST_ANGLE          = 212.43017 <DEG>
+RA_DEC_REF_PIXEL     = (512.00000,512.00000)
+RETICLE_POINT_RA     = (286.18172 <DEG>,284.89969 <DEG>,287.00146 <DEG>,
+  285.71292 <DEG>)
+RETICLE_POINT_DECLINATION = (12.74731 <DEG>,11.95067 <DEG>,11.48768 <DEG>,
+  10.68847 <DEG>)
+
+/*** TARGET PARAMETERS ***/
+SC_TARGET_POSITION_VECTOR = (-7282598.25457 <KM>,25612610.91152 <KM>,
+  -5411326.66758 <KM>)
+TARGET_CENTER_DISTANCE = 27172127.83986 <KM>
+
+/*** TARGET WITHIN SENSOR FOV ***/
+SLANT_DISTANCE       = "N/A"
+CENTER_LATITUDE      = "N/A"
+CENTER_LONGITUDE     = "N/A"
+HORIZONTAL_PIXEL_SCALE = "N/A"
+VERTICAL_PIXEL_SCALE = "N/A"
+SMEAR_MAGNITUDE      = "N/A"
+SMEAR_AZIMUTH        = "N/A"
+NORTH_AZIMUTH        = "N/A"
+RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+
+/*** SPACECRAFT POSITION WITH RESPECT TO CENTRAL BODY ***/
+SUB_SPACECRAFT_LATITUDE = -11.49546 <DEG>
+SUB_SPACECRAFT_LONGITUDE = 283.33197 <DEG>
+SPACECRAFT_ALTITUDE  = 27165750.55671 <KM>
+SUB_SPACECRAFT_AZIMUTH = "N/A"
+
+/*** SPACECRAFT LOCATION ***/
+SPACECRAFT_SOLAR_DISTANCE = 139069138.64129 <KM>
+SC_SUN_POSITION_VECTOR = (-87690987.23333 <KM>,-92023335.85736 <KM>,
+  -56411184.51298 <KM>)
+SC_SUN_VELOCITY_VECTOR = (-24.04359 <KM/S>,19.51186 <KM/S>,7.92341 <KM/S>)
+
+/*** VIEWING AND LIGHTING GEOMETRY (SUN ON TARGET) ***/
+SOLAR_DISTANCE       = 151343022.60304 <KM>
+SUB_SOLAR_AZIMUTH    = "N/A"
+SUB_SOLAR_LATITUDE   = 19.70999 <DEG>
+SUB_SOLAR_LONGITUDE  = 233.12030 <DEG>
+INCIDENCE_ANGLE      = "N/A"
+PHASE_ANGLE          = "N/A"
+EMISSION_ANGLE       = "N/A"
+LOCAL_HOUR_ANGLE     = "N/A"
+
+/*** GEOMETRY FOR EACH SUBFRAME ***/
+GROUP = SUBFRAME1_PARAMETERS
+  RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+  RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+END_GROUP = SUBFRAME1_PARAMETERS
+
+GROUP = SUBFRAME2_PARAMETERS
+  RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+  RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+END_GROUP = SUBFRAME2_PARAMETERS
+
+GROUP = SUBFRAME3_PARAMETERS
+  RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+  RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+END_GROUP = SUBFRAME3_PARAMETERS
+
+GROUP = SUBFRAME4_PARAMETERS
+  RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+  RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+END_GROUP = SUBFRAME4_PARAMETERS
+
+GROUP = SUBFRAME5_PARAMETERS
+  RETICLE_POINT_LATITUDE = ("N/A","N/A","N/A","N/A")
+  RETICLE_POINT_LONGITUDE = ("N/A","N/A","N/A","N/A")
+END_GROUP = SUBFRAME5_PARAMETERS
+
+
+OBJECT = IMAGE
+  LINES              = 1024
+  LINE_SAMPLES       = 1024
+  SAMPLE_TYPE        = MSB_UNSIGNED_INTEGER
+  SAMPLE_BITS        = 16
+  UNIT               = "N/A"
+  DARK_STRIP_MEAN    = 267.777
+
+/*** IMAGE STATISTICS OF  ***/
+/*** THE EXPOSED CCD AREA ***/
+  MINIMUM            = 262.000
+  MAXIMUM            = 2978.000
+  MEAN               = 267.684
+  STANDARD_DEVIATION = 17.810
+
+/*** PIXEL COUNTS ***/
+  SATURATED_PIXEL_COUNT = 0
+  MISSING_PIXELS     = 0
+END_OBJECT = IMAGE
+END
+    """
+
+def test_mdis_creation(mdislabel):
+    with Messenger(mdislabel) as m:
+        d = m.to_dict()
+        assert isinstance(d, dict)
diff --git a/tests/pytests/test_mro_drivers.py b/tests/pytests/test_mro_drivers.py
new file mode 100644
index 0000000000000000000000000000000000000000..00b48f0d8a5616a372ce6c44b324cef6833f77a0
--- /dev/null
+++ b/tests/pytests/test_mro_drivers.py
@@ -0,0 +1,69 @@
+import pytest
+
+import ale
+from ale.drivers.mro_driver import MRO_CTX
+from ale.drivers import mro_driver, base, distortion
+
+# 'Mock' the spice module where it is imported
+from conftest import SimpleSpice, get_mockkernels
+
+simplespice = SimpleSpice()
+base.spice = simplespice
+mro_driver.spice = simplespice
+distortion.spice = simplespice
+
+MRO_CTX.metakernel = get_mockkernels
+
+@pytest.fixture
+def mroctx_label():
+    return """
+    PDS_VERSION_ID = PDS3
+    FILE_NAME = "D10_031011_1864_XI_06N201W.IMG"
+    RECORD_TYPE = FIXED_LENGTH
+    RECORD_BYTES = 5056
+    FILE_RECORDS = 7169
+    LABEL_RECORDS = 1
+    ^IMAGE = 2
+    SPACECRAFT_NAME = MARS_RECONNAISSANCE_ORBITER
+    INSTRUMENT_NAME = "CONTEXT CAMERA"
+    INSTRUMENT_HOST_NAME = "MARS RECONNAISSANCE ORBITER"
+    MISSION_PHASE_NAME = "ESP"
+    TARGET_NAME = MARS
+    INSTRUMENT_ID = CTX
+    PRODUCER_ID = MRO_CTX_TEAM
+    DATA_SET_ID = "MRO-M-CTX-2-EDR-L0-V1.0"
+    PRODUCT_CREATION_TIME = 2013-08-27T20:37:16
+    SOFTWARE_NAME = "makepds05 $Revision: 1.16 $"
+    UPLOAD_ID = "UNK"
+    ORIGINAL_PRODUCT_ID = "4A_04_109D009200"
+    PRODUCT_ID = "D10_031011_1864_XI_06N201W"
+    START_TIME = 2013-03-08T21:38:44.237
+    STOP_TIME = 2013-03-08T21:38:57.689
+    SPACECRAFT_CLOCK_START_COUNT = "1047245959:234"
+    SPACECRAFT_CLOCK_STOP_COUNT = "N/A"
+    FOCAL_PLANE_TEMPERATURE = 298.0 <K>
+    SAMPLE_BIT_MODE_ID = "SQROOT"
+    OFFSET_MODE_ID = "196/234/217"
+    LINE_EXPOSURE_DURATION = 1.877 <MSEC>
+    SAMPLING_FACTOR = 1
+    SAMPLE_FIRST_PIXEL = 0
+    RATIONALE_DESC = "Dark slope streak monitor in MOC SP1-25706 and E05-01077 and others"
+    DATA_QUALITY_DESC = "OK"
+    ORBIT_NUMBER = 31011
+    OBJECT = IMAGE
+    LINES = 7168
+    LINE_SAMPLES = 5056
+    LINE_PREFIX_BYTES = 0
+    LINE_SUFFIX_BYTES = 0
+    SAMPLE_TYPE = UNSIGNED_INTEGER
+    SAMPLE_BITS = 8
+    SAMPLE_BIT_MASK = 2#11111111#
+    CHECKSUM = 16#0C902B7F#
+    END_OBJECT = IMAGE
+    END"""
+
+
+def test_get_dict(mroctx_label):
+    with MRO_CTX(mroctx_label) as m:
+        d = m.to_dict()
+    assert isinstance(d, dict)