From d397cd05c0f83a84cee2514b9f7ff2e1cda63ba8 Mon Sep 17 00:00:00 2001
From: acpaquette <acpaquette@usgs.gov>
Date: Mon, 15 May 2023 15:41:03 -0700
Subject: [PATCH] Projection Addition Fixes (#528)

* Attached the projection to isd if it is a non-empty dtring

* Fixed projected image tests

* Added all change log entries up to current ALE

* Added changelog entry for current PR

* Removed leftover debug prints
---
 CHANGELOG.md                            | 11 +++++++++++
 ale/base/base.py                        | 17 +++++++++--------
 ale/formatters/formatter.py             |  5 +++--
 ale/formatters/usgscsm_formatter.py     |  5 +++--
 tests/pytests/test_formatter.py         | 18 +++++++++++++++++-
 tests/pytests/test_mex_drivers.py       |  4 +---
 tests/pytests/test_mro_drivers.py       |  2 ++
 tests/pytests/test_usgscsm_formatter.py |  6 +++---
 8 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58ce1c7..16e6275 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -35,3 +35,14 @@ release.
 
 ## [Unreleased]
 
+### Fixed
+- Kaguya IsisLabelIsisSpice now calculates the right exposure_duration and focal2pixel_lines [#487](https://github.com/DOI-USGS/ale/pull/487)
+- Logging from generate_isd now correctly limits logging information [#487](https://github.com/DOI-USGS/ale/pull/487)
+
+### Changed
+- Projection information is only written to the ISD if a projection is present instead of writing an empty projection [#528](https://github.com/DOI-USGS/ale/pull/528/)
+
+### Added
+- Projection information (through GDAL) will be attached to the ISD if a projected product is processed through ALE [#524](https://github.com/DOI-USGS/ale/pull/524)
+- Kaguya IsisLabelNaifSpice driver, tests, and test data [#487](https://github.com/DOI-USGS/ale/pull/487)
+- Hayabusa Amica IsisLabelNaifSpice driver, tests and test data [#521](https://github.com/DOI-USGS/ale/pull/521)
\ No newline at end of file
diff --git a/ale/base/base.py b/ale/base/base.py
index 1df9c7e..6fba266 100644
--- a/ale/base/base.py
+++ b/ale/base/base.py
@@ -336,26 +336,27 @@ class Driver():
                 self._projection = ""
                 return self._projection
 
+            geodata = None
             if isinstance(self._file, pvl.PVLModule):
                 # save it to a temp folder
                 with tempfile.NamedTemporaryFile() as tmp:
                     tmp.write(pvl.dumps(self._file)) 
 
                     geodata = gdal.Open(tempfile.name)
-                    self._projection = geodata.GetSpatialRef()
             else: 
                 # should be a path
                 if not os.path.exists(self._file): 
                     self._projection = "" 
                 else: 
                     geodata = gdal.Open(self._file)
-                    self._projection = geodata.GetSpatialRef()
-
-            # is None if not projected
-            if self._projection: 
-                self._projection = self._projection.ExportToProj4()
-            else: 
-                self._projection = "" 
+   
+
+            # Try to get the projection, if we are unsuccessful set it
+            # to empty
+            try:
+              self._projection = geodata.GetSpatialRef().ExportToProj4()
+            except:
+              self._projection = "" 
         return self._projection
     
 
diff --git a/ale/formatters/formatter.py b/ale/formatters/formatter.py
index 23968d6..6de1913 100644
--- a/ale/formatters/formatter.py
+++ b/ale/formatters/formatter.py
@@ -196,8 +196,9 @@ def to_isd(driver):
 
     meta_data['sun_position'] = sun_position
 
-    meta_data["projection"] = driver.projection 
-    meta_data["geotransform"] = driver.geotransform 
+    if (driver.projection != ""):
+        meta_data["projection"] = driver.projection
+        meta_data["geotransform"] = driver.geotransform
 
     # check that there is a valid sensor model name
     if 'name_model' not in meta_data:
diff --git a/ale/formatters/usgscsm_formatter.py b/ale/formatters/usgscsm_formatter.py
index 44438fd..1a63284 100644
--- a/ale/formatters/usgscsm_formatter.py
+++ b/ale/formatters/usgscsm_formatter.py
@@ -51,8 +51,9 @@ def to_usgscsm(driver):
         'unit' : 'm'
     }
 
-    isd_data["projection"] = driver.projection
-    isd_data["geotransform"] = driver.geotransform
+    if (driver.projection != ""):
+        isd_data["projection"] = driver.projection
+        isd_data["geotransform"] = driver.geotransform
 
     # shared isd keywords for Framer and Linescanner
     if isinstance(driver, LineScanner) or isinstance(driver, Framer):
diff --git a/tests/pytests/test_formatter.py b/tests/pytests/test_formatter.py
index 64a8054..1c567ac 100644
--- a/tests/pytests/test_formatter.py
+++ b/tests/pytests/test_formatter.py
@@ -9,6 +9,8 @@ from ale.transformation import FrameChain
 from ale.base.data_naif import NaifSpice
 from ale.rotation import ConstantRotation, TimeDependentRotation
 
+from conftest import get_image_label
+
 class DummyNaifSpiceDriver(Driver, NaifSpice):
     """
     Test Driver implementation with dummy values
@@ -169,7 +171,6 @@ class DummyLineScannerDriver(LineScanner, DummyNaifSpiceDriver):
     def exposure_duration(self):
         return .01
 
-
 @pytest.fixture
 def driver():
     return DummyFramerDriver('')
@@ -348,3 +349,18 @@ def test_naif_keywords(driver):
         'keyword_1' : 0,
         'keyword_2' : 'test'
     }
+
+def test_no_projection(test_frame_driver):
+    isd = formatter.to_isd(test_frame_driver)
+    # isn't using real projection so it should be None
+    assert isd.get("projection", None) == None
+
+def test_isis_projection():
+    isd = formatter.to_isd(DummyLineScannerDriver(get_image_label('B10_013341_1010_XN_79S172W', "isis3")))
+    assert isd.get("projection", None) == "+proj=sinu +lon_0=148.36859083039 +x_0=0 +y_0=0 +R=3396190 +units=m +no_defs"
+
+def test_isis_geotransform():
+    isd = formatter.to_isd(DummyLineScannerDriver(get_image_label('B10_013341_1010_XN_79S172W', "isis3")))
+    expected = (-219771.1526456, 1455.4380969907, 0.0, 5175537.8728989, 0.0, -1455.4380969907)
+    for value, truth in zip(isd.get("geotransform", None), expected):
+        pytest.approx(value, truth)
diff --git a/tests/pytests/test_mex_drivers.py b/tests/pytests/test_mex_drivers.py
index ec5035c..650d9b4 100644
--- a/tests/pytests/test_mex_drivers.py
+++ b/tests/pytests/test_mex_drivers.py
@@ -202,9 +202,7 @@ def usgscsm_compare_dict():
               "t0_ephemeris": -101.83713859319687,
               "dt_ephemeris": 40.734855437278746,
               "t0_quaternion": -101.83713859319687,
-              "dt_quaternion": 40.734855437278746,
-              "projection" : "",
-              "geotransform" : (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)
+              "dt_quaternion": 40.734855437278746
               },
 
         "isis" :
diff --git a/tests/pytests/test_mro_drivers.py b/tests/pytests/test_mro_drivers.py
index dc007ea..3515e74 100644
--- a/tests/pytests/test_mro_drivers.py
+++ b/tests/pytests/test_mro_drivers.py
@@ -59,6 +59,8 @@ def test_mro_ctx_load(test_ctx_kernels, label_type, kernel_type):
 
     if label_type == 'isis3' and kernel_type == 'naif':
         compare_isd['image_samples'] = 5000
+        compare_isd["projection"] = '+proj=sinu +lon_0=148.36859083039 +x_0=0 +y_0=0 +R=3396190 +units=m +no_defs'
+        compare_isd["geotransform"] = [-219771.1526456, 1455.4380969907, 0.0, 5175537.8728989, 0.0, -1455.4380969907]
 
     comparison = compare_dicts(isd_obj, compare_isd)
     assert comparison == []
diff --git a/tests/pytests/test_usgscsm_formatter.py b/tests/pytests/test_usgscsm_formatter.py
index 70ecb64..35bacb9 100644
--- a/tests/pytests/test_usgscsm_formatter.py
+++ b/tests/pytests/test_usgscsm_formatter.py
@@ -348,16 +348,16 @@ def test_line_scan_sun_position(test_line_scan_driver):
 def test_no_projection(test_frame_driver):
     isd = usgscsm_formatter.to_usgscsm(test_frame_driver)
     # isn't using real projection so it should be None
-    assert isd['projection'] == None
+    assert isd.get("projection", None) == None
 
 def test_isis_projection():
     isd = usgscsm_formatter.to_usgscsm(TestLineScanner(get_image_label('B10_013341_1010_XN_79S172W', "isis3")))
-    assert isd["projection"] == "+proj=sinu +lon_0=148.36859083039 +x_0=0 +y_0=0 +R=3396190 +units=m +no_defs"
+    assert isd.get("projection", None) == "+proj=sinu +lon_0=148.36859083039 +x_0=0 +y_0=0 +R=3396190 +units=m +no_defs"
 
 
 def test_isis_geotransform():
     isd = usgscsm_formatter.to_usgscsm(TestLineScanner(get_image_label('B10_013341_1010_XN_79S172W', "isis3")))
     expected = (-219771.1526456, 1455.4380969907, 0.0, 5175537.8728989, 0.0, -1455.4380969907)
-    for value, truth in zip(isd["geotransform"], expected):
+    for value, truth in zip(isd.get("geotransform", None), expected):
         pytest.approx(value, truth)
 
-- 
GitLab