From e15882319eea0f5a4fcc119278436ea7268452bd Mon Sep 17 00:00:00 2001
From: Jay Laura <jlaura@usgs.gov>
Date: Sat, 8 Jun 2024 05:55:22 -0700
Subject: [PATCH] Fixes scale/offset error. (#206)

* Fixes scale/offset error.

* Adds ISIS CSM support

* Reverts millisecond formatting

* Adds missing CHANGELOG.

* Adds exception handling
---
 CHANGELOG.md                  |  6 +++++-
 plio/io/__init__.py           |  1 +
 plio/io/io_gdal.py            |  4 ++--
 plio/io/isis_serial_number.py | 38 ++++++++++++++++++++---------------
 4 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 48847eb..b86dca2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -34,8 +34,12 @@ release.
 -->
 
 ## [Unreleased]
+### Added
+- Hard coded support for `csminit`ed cubes that have serial numbers that differ from `spiceinit`ed cubes.
+- Added support for scale and offset for GeoDataset objects.
+
 ### Fixed
-- Fixed a bug where scale and offset were not being read or applied to GeoDataset objects.
+- Fixed a bug where scale and offset were being applied backwards to GeoDataset objects.
 
 ## [1.5.5]()
 ### Fixed
diff --git a/plio/io/__init__.py b/plio/io/__init__.py
index b67fa43..7baf574 100644
--- a/plio/io/__init__.py
+++ b/plio/io/__init__.py
@@ -6,6 +6,7 @@ try:
     gdal = importlib.import_module('osgeo.gdal')
     osr = importlib.import_module('osgeo.osr')
     ogr = importlib.import_module('osgeo.ogr')
+    gdal.UseExceptions()
 except:
     gdal = osr = ogr = None
 
diff --git a/plio/io/io_gdal.py b/plio/io/io_gdal.py
index f67ca5b..07c83a1 100644
--- a/plio/io/io_gdal.py
+++ b/plio/io/io_gdal.py
@@ -517,7 +517,7 @@ class GeoDataset(object):
         dtype = getattr(np, dtype)
 
         if not pixels:
-            array = (band.ReadAsArray().astype(dtype) + offset) * scale
+            array = band.ReadAsArray().astype(dtype) * scale + offset
             #if self.north_up == False:
             #    array = np.flipud(array)
         else:
@@ -538,7 +538,7 @@ class GeoDataset(object):
 
             if ystart + ycount > ymax:
                 ycount = ymax - ystart
-            array = (band.ReadAsArray(xstart, ystart, xcount, ycount).astype(dtype) + offset) * scale
+            array = band.ReadAsArray(xstart, ystart, xcount, ycount).astype(dtype) * scale + offset
 
         return array
 
diff --git a/plio/io/isis_serial_number.py b/plio/io/isis_serial_number.py
index 725e9a1..1c64a8d 100644
--- a/plio/io/isis_serial_number.py
+++ b/plio/io/isis_serial_number.py
@@ -36,22 +36,28 @@ def get_isis_translation(label):
     if not isinstance(label, PVLModule):
         label = pvl.load(label)
 
-    # Grab the spacecraft name and run it through the ISIS lookup
-    spacecraft_name = find_in_dict(label, 'SpacecraftName')
-    for row in plio.data_session.query(StringToMission).filter(StringToMission.key==spacecraft_name):
-        spacecraft_name = row.value.lower()
-    # Try and pull an instrument identifier
-    try:
-        instrumentid = find_in_dict(label, 'InstrumentId').capitalize()
-    except:
-        instrumentid = None
-
-    translation = None
-    # Grab the translation PVL object using the lookup
-    for row in plio.data_session.query(Translations).filter(Translations.mission==spacecraft_name,
-                                                            Translations.instrument==instrumentid):
-        # Convert the JSON back to a PVL object
-        translation = PVLModule(row.translation)
+    if find_in_dict(label, 'CsmInfo'):
+        # This cube has been CSM inited, have to load the CSM translation table
+        translation = {"Keyword1": {"InputKey": "CSMPlatformID", "InputGroup": "IsisCube,CsmInfo", "InputPosition": ["IsisCube", "CsmInfo"], "OutputName": "Keyword1", "OutputPosition": ["Group", "SerialNumberKeywords"], "Translation": ["*", "*"]}, "Keyword2": {"InputKey": "CSMInstrumentId", "InputGroup": "IsisCube,CsmInfo", "InputPosition": ["IsisCube", "CsmInfo"], "OutputName": "Keyword2", "OutputPosition": ["Group", "SerialNumberKeywords"], "Translation": ["*", "*"]}, "Keyword3": {"InputKey": "ReferenceTime", "InputGroup": "IsisCube,CsmInfo", "InputPosition": ["IsisCube", "CsmInfo"], "OutputName": "Keyword3", "OutputPosition": ["Group", "SerialNumberKeywords"], "Translation": ["*", "*"]}}
+    else:
+        # Grab the spacecraft name and run it through the ISIS lookup
+        spacecraft_name = find_in_dict(label, 'SpacecraftName')
+        for row in plio.data_session.query(StringToMission).filter(StringToMission.key==spacecraft_name):
+            spacecraft_name = row.value.lower()
+        
+        # Try and pull an instrument identifier
+        try:
+            instrumentid = find_in_dict(label, 'InstrumentId').capitalize()
+        except:
+            instrumentid = None
+
+        translation = None
+        # Grab the translation PVL object using the lookup
+        for row in plio.data_session.query(Translations).filter(Translations.mission==spacecraft_name,
+                                                                Translations.instrument==instrumentid):
+            # Convert the JSON back to a PVL object
+            translation = PVLModule(row.translation)
+
     return translation
 
 
-- 
GitLab