From cc01d0e31b68aae74ebd01cee176a38e3f08bdff Mon Sep 17 00:00:00 2001
From: Jesse Mapel <jmapel@usgs.gov>
Date: Fri, 6 May 2022 14:08:46 -0700
Subject: [PATCH] More WAC filter specific changes and Python 3.10 updates
 (#452)

* Added Python 3.10 CI

* Added more filter specific LRO WAC props

* Updated container import for 3.10
---
 .github/workflows/ci_testing.yml  |   2 +-
 ale/drivers/lro_drivers.py        | 138 ++++++++++++++++++++++++------
 tests/pytests/test_lro_drivers.py |  12 +--
 3 files changed, 115 insertions(+), 37 deletions(-)

diff --git a/.github/workflows/ci_testing.yml b/.github/workflows/ci_testing.yml
index ed7d728..5ce7149 100644
--- a/.github/workflows/ci_testing.yml
+++ b/.github/workflows/ci_testing.yml
@@ -15,7 +15,7 @@ jobs:
       fail-fast: false
       matrix:
        os: [ubuntu-latest, macos-latest]
-       python-version: ["3.7", "3.8", "3.9"]
+       python-version: ["3.7", "3.8", "3.9", "3.10"]
     defaults:
       run:
         shell: bash -l {0}
diff --git a/ale/drivers/lro_drivers.py b/ale/drivers/lro_drivers.py
index 5eb3f72..0fadd79 100644
--- a/ale/drivers/lro_drivers.py
+++ b/ale/drivers/lro_drivers.py
@@ -952,6 +952,76 @@ class LroLrocWacIsisLabelIsisSpiceDriver(PushFrame, IsisLabel, IsisSpice, Radial
         elif self.instrument_id == "LRO_LROCWAC_VIS":
             return 14
 
+
+    @property
+    def pixel2focal_x(self):
+        """
+        Expects fikid to be defined. This must be the integer Naif id code of the filter
+
+        Returns
+        -------
+        : list<double>
+        detector to focal plane x
+        """
+        return self.naif_keywords.get('INS{}_TRANSX'.format(self.fikid), None)
+
+
+    @property
+    def pixel2focal_y(self):
+        """
+        Expects fikid to be defined. This must be the integer Naif id code of the filter
+
+        Returns
+        -------
+        : list<double>
+        detector to focal plane y
+        """
+        return self.naif_keywords.get('INS{}_TRANSY'.format(self.fikid), None)
+
+    @property
+    def focal_length(self):
+        """
+        The focal length of the instrument
+        Expects naif_keywords to be defined. This should be a dict containing
+        Naif keywords from the label.
+        Expects fikid to be defined. This should be the integer Naif ID code
+        for the filter.
+
+        Returns
+        -------
+        float :
+            The focal length in millimeters
+        """
+        return self.naif_keywords.get('INS{}_FOCAL_LENGTH'.format(self.fikid), None)
+
+    @property
+    def detector_center_sample(self):
+        """
+        The center of the CCD in detector pixels
+        Expects fikid to be defined. This should be the integer Naif ID code
+        for the filter.
+
+        Returns
+        -------
+        list :
+            The center of the CCD formatted as line, sample
+        """
+        return self.naif_keywords.get('INS{}_BORESIGHT_SAMPLE'.format(self.fikid), None)
+
+    @property
+    def detector_center_line(self):
+        """
+        The center of the CCD in detector pixels
+        Expects fikid to be defined. This should be the integer Naif ID code
+        for the filter.
+
+        Returns
+        -------
+        list :
+            The center of the CCD formatted as line, sample
+        """
+        return self.naif_keywords.get('INS{}_BORESIGHT_LINE'.format(self.fikid), None)
+
 class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, RadialDistortion, Driver):
     """
     Driver for Lunar Reconnaissance Orbiter WAC ISIS cube
@@ -999,34 +1069,6 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial
         return self._ephemeris_start_time
 
 
-    @property
-    def detector_center_line(self):
-        """
-        The center of the CCD in detector pixels
-        ISIS uses 0.5 based CCD lines, so we need to convert to 0 based.
-
-        Returns
-        -------
-        float :
-            The center line of the CCD
-        """
-        return super().detector_center_line - 0.5
-
-
-    @property
-    def detector_center_sample(self):
-        """
-        The center of the CCD in detector pixels
-        ISIS uses 0.5 based CCD samples, so we need to convert to 0 based.
-
-        Returns
-        -------
-        float :
-            The center sample of the CCD
-        """
-        return super().detector_center_sample - 0.5
-
-
     @property
     def sensor_name(self):
         """
@@ -1203,3 +1245,43 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial
         except (IndexError, TypeError):
             pass
         return super().detector_start_line + offset
+
+    @property
+    def focal_length(self):
+        """
+        Returns the focal length of the sensor
+        Expects fikid to be defined. This must be the integer Naif id code of
+        the filter.
+
+        Returns
+        -------
+        : float
+          focal length
+        """
+        return float(spice.gdpool('INS{}_FOCAL_LENGTH'.format(self.fikid), 0, 1)[0])
+
+    @property
+    def detector_center_sample(self):
+        """
+        Returns the center detector sample. Expects ikid to be defined. This should
+        be an integer containing the Naif Id code of the instrument.
+
+        Returns
+        -------
+        : float
+          Detector sample of the principal point
+        """
+        return float(spice.gdpool('INS{}_BORESIGHT_SAMPLE'.format(self.fikid), 0, 1)[0]) - 0.5
+
+    @property
+    def detector_center_line(self):
+        """
+        Returns the center detector line. Expects ikid to be defined. This should
+        be an integer containing the Naif Id code of the instrument.
+
+        Returns
+        -------
+        : float
+          Detector line of the principal point
+        """
+        return float(spice.gdpool('INS{}_BORESIGHT_LINE'.format(self.fikid), 0, 1)[0]) - 0.5
diff --git a/tests/pytests/test_lro_drivers.py b/tests/pytests/test_lro_drivers.py
index e16d1d6..a58ee59 100644
--- a/tests/pytests/test_lro_drivers.py
+++ b/tests/pytests/test_lro_drivers.py
@@ -288,18 +288,14 @@ class test_wac_isis_naif(unittest.TestCase):
             scs2e.assert_called_with(-85, '1/274692469:15073')
 
     def test_detector_center_sample(self):
-        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
-             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
+        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool:
             assert self.driver.detector_center_sample == 0.5
-            gdpool.assert_called_with('INS-12345_BORESIGHT_SAMPLE', 0, 1)
-            bods2c.assert_called_with('LRO_LROCWAC_UV')
+            gdpool.assert_called_with('INS-85641_BORESIGHT_SAMPLE', 0, 1)
 
     def test_detector_center_line(self):
-        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
-             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
+        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool:
             assert self.driver.detector_center_line == 0.5
-            gdpool.assert_called_with('INS-12345_BORESIGHT_LINE', 0, 1)
-            bods2c.assert_called_with('LRO_LROCWAC_UV')
+            gdpool.assert_called_with('INS-85641_BORESIGHT_LINE', 0, 1)
 
     def test_odtk(self):
         with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool:
-- 
GitLab