From 63651c4cfbd9b8b277c321e5e88c66a14583ebad Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Mon, 30 Mar 2026 17:07:03 -0700 Subject: [PATCH 1/8] get_naif_keywords, throw exception if not found --- ale/base/data_isis.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/ale/base/data_isis.py b/ale/base/data_isis.py index 27c58b9c5..a4ecb3e0a 100644 --- a/ale/base/data_isis.py +++ b/ale/base/data_isis.py @@ -15,6 +15,7 @@ from scipy.interpolate import interp1d, BPoly from ale.base.label_isis import IsisLabel +from ale.base import get_naif_keyword def read_table_data(table_label, cube): """ @@ -147,6 +148,11 @@ def rotate_state(table, rotation): rotated_vel = None return rotated_pos, rotated_vel, ephemeris_times +def get_naif_keyword(self, ale_name, naif_key): + val = self.naif_keywords.get(naif_key, None) + if val is None: + raise Exception('Could not find a value for {} using the NAIF Keyword {}'.format(ale_name, naif_key)) + return val class IsisSpice(): """ Mixin class for reading from an ISIS cube that has been spiceinit'd @@ -350,7 +356,9 @@ def detector_center_sample(self): list : The center of the CCD formatted as line, sample """ - return self.naif_keywords.get('INS{}_BORESIGHT_SAMPLE'.format(self.ikid), None) + + return get_naif_keyword(self, 'detector_center_sample', 'INS{}_BORESIGHT_SAMPLE'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_BORESIGHT_SAMPLE'.format(self.ikid), None) @property def detector_center_line(self): @@ -364,7 +372,8 @@ def detector_center_line(self): list : The center of the CCD formatted as line, sample """ - return self.naif_keywords.get('INS{}_BORESIGHT_LINE'.format(self.ikid), None) + return get_naif_keyword(self, 'detector_center_line', 'INS{}_BORESIGHT_LINE'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_BORESIGHT_LINE'.format(self.ikid), None) @property @@ -430,7 +439,8 @@ def focal2pixel_lines(self): The coefficients of the affine transformation formatted as constant, x, y """ - return self.naif_keywords.get('INS{}_ITRANSL'.format(self.ikid), None) + return get_naif_keyword(self, 'focal2pixel_lines', 'INS{}_ITRANSL'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_ITRANSL'.format(self.ikid), None) @property def focal2pixel_samples(self): @@ -448,7 +458,8 @@ def focal2pixel_samples(self): The coefficients of the affine transformation formatted as constant, x, y """ - return self.naif_keywords.get('INS{}_ITRANSS'.format(self.ikid), None) + return get_naif_keyword(self, 'focal2pixel_samples', 'INS{}_ITRANSS'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_ITRANSS'.format(self.ikid), None) @property def pixel2focal_x(self): @@ -461,7 +472,8 @@ def pixel2focal_x(self): detector to focal plane x """ - return self.naif_keywords.get('INS{}_TRANSX'.format(self.ikid), None) + return get_naif_keyword(self, 'pixel2focal_x', 'INS{}_TRANSX'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_TRANSX'.format(self.ikid), None) @property def pixel2focal_y(self): @@ -474,7 +486,8 @@ def pixel2focal_y(self): detector to focal plane y """ - return self.naif_keywords.get('INS{}_TRANSY'.format(self.ikid), None) + return get_naif_keyword(self, 'pixel2focal_y', 'INS{}_TRANSY'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_TRANSY'.format(self.ikid), None) @property def focal_length(self): @@ -490,7 +503,9 @@ def focal_length(self): float : The focal length in millimeters """ - return self.naif_keywords.get('INS{}_FOCAL_LENGTH'.format(self.ikid), None) + + return get_naif_keyword(self, 'focal_length', 'INS{}_FOCAL_LENGTH'.format(self.ikid)) + #return self.naif_keywords.get('INS{}_FOCAL_LENGTH'.format(self.ikid), None) @property def target_body_radii(self): From 288500ea498a86fe4bd25d98d73bebb3b9e1a1c9 Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 12:59:46 -0700 Subject: [PATCH 2/8] Test bad naif keywords --- ale/base/data_isis.py | 3 +-- tests/pytests/test_data_isis.py | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ale/base/data_isis.py b/ale/base/data_isis.py index a4ecb3e0a..86a93114c 100644 --- a/ale/base/data_isis.py +++ b/ale/base/data_isis.py @@ -15,7 +15,6 @@ from scipy.interpolate import interp1d, BPoly from ale.base.label_isis import IsisLabel -from ale.base import get_naif_keyword def read_table_data(table_label, cube): """ @@ -151,7 +150,7 @@ def rotate_state(table, rotation): def get_naif_keyword(self, ale_name, naif_key): val = self.naif_keywords.get(naif_key, None) if val is None: - raise Exception('Could not find a value for {} using the NAIF Keyword {}'.format(ale_name, naif_key)) + raise LookupError('Could not find a value for {} using the NAIF Keyword {}'.format(ale_name, naif_key)) return val class IsisSpice(): """ diff --git a/tests/pytests/test_data_isis.py b/tests/pytests/test_data_isis.py index 482266273..82bd6c489 100644 --- a/tests/pytests/test_data_isis.py +++ b/tests/pytests/test_data_isis.py @@ -714,3 +714,10 @@ def test_no_tables(): test_mix_in.inst_position_table with pytest.raises(ValueError): test_mix_in.sun_position_table + +def testdata_bad_naif_keywords(): + # Remove ITRANSL + testlabel_bad_naif_keywords = "\n".join([line for line in testlabel.splitlines() if "ITRANSL" not in line]) + isis_spice = IsisSpice() + with pytest.raises(LookupError): + isis_spice.label = pvl.loads(testlabel_bad_naif_keywords) \ No newline at end of file From df6267525eb69367239b23af6bc7988751f7c484 Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 13:18:19 -0700 Subject: [PATCH 3/8] test try catch --- tests/pytests/test_data_isis.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/pytests/test_data_isis.py b/tests/pytests/test_data_isis.py index 82bd6c489..9ca44d02c 100644 --- a/tests/pytests/test_data_isis.py +++ b/tests/pytests/test_data_isis.py @@ -719,5 +719,9 @@ def testdata_bad_naif_keywords(): # Remove ITRANSL testlabel_bad_naif_keywords = "\n".join([line for line in testlabel.splitlines() if "ITRANSL" not in line]) isis_spice = IsisSpice() - with pytest.raises(LookupError): - isis_spice.label = pvl.loads(testlabel_bad_naif_keywords) \ No newline at end of file + # with pytest.raises(LookupError): + try: + isis_spice.label = pvl.loads(testlabel_bad_naif_keywords) + assert False + except Exception as load_failure: + assert str(load_failure) == "No Such Driver for Label" \ No newline at end of file From 68eabd8647a9dac970d8add1b527f96156e31e9c Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 13:32:03 -0700 Subject: [PATCH 4/8] test detector center line samle --- tests/pytests/test_data_isis.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/tests/pytests/test_data_isis.py b/tests/pytests/test_data_isis.py index 9ca44d02c..66d6eddb3 100644 --- a/tests/pytests/test_data_isis.py +++ b/tests/pytests/test_data_isis.py @@ -519,11 +519,13 @@ def test_sun_position(testdata): def test_detector_center_sample(testdata): - assert testdata.detector_center_sample == None + with pytest.raises(LookupError): + testdata.detector_center_sample def test_detector_center_line(testdata): - assert testdata.detector_center_line == None + with pytest.raises(LookupError): + testdata.detector_center_line def test_focal_length(testdata): @@ -713,15 +715,4 @@ def test_no_tables(): with pytest.raises(ValueError): test_mix_in.inst_position_table with pytest.raises(ValueError): - test_mix_in.sun_position_table - -def testdata_bad_naif_keywords(): - # Remove ITRANSL - testlabel_bad_naif_keywords = "\n".join([line for line in testlabel.splitlines() if "ITRANSL" not in line]) - isis_spice = IsisSpice() - # with pytest.raises(LookupError): - try: - isis_spice.label = pvl.loads(testlabel_bad_naif_keywords) - assert False - except Exception as load_failure: - assert str(load_failure) == "No Such Driver for Label" \ No newline at end of file + test_mix_in.sun_position_table \ No newline at end of file From 5c66f17ece845bef5656628a251ec4b9a3c4eecb Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 13:48:59 -0700 Subject: [PATCH 5/8] remove old code --- ale/base/data_isis.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/ale/base/data_isis.py b/ale/base/data_isis.py index 86a93114c..849beee5a 100644 --- a/ale/base/data_isis.py +++ b/ale/base/data_isis.py @@ -357,7 +357,6 @@ def detector_center_sample(self): """ return get_naif_keyword(self, 'detector_center_sample', 'INS{}_BORESIGHT_SAMPLE'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_BORESIGHT_SAMPLE'.format(self.ikid), None) @property def detector_center_line(self): @@ -372,7 +371,6 @@ def detector_center_line(self): The center of the CCD formatted as line, sample """ return get_naif_keyword(self, 'detector_center_line', 'INS{}_BORESIGHT_LINE'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_BORESIGHT_LINE'.format(self.ikid), None) @property @@ -439,7 +437,6 @@ def focal2pixel_lines(self): formatted as constant, x, y """ return get_naif_keyword(self, 'focal2pixel_lines', 'INS{}_ITRANSL'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_ITRANSL'.format(self.ikid), None) @property def focal2pixel_samples(self): @@ -458,7 +455,6 @@ def focal2pixel_samples(self): formatted as constant, x, y """ return get_naif_keyword(self, 'focal2pixel_samples', 'INS{}_ITRANSS'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_ITRANSS'.format(self.ikid), None) @property def pixel2focal_x(self): @@ -472,7 +468,6 @@ def pixel2focal_x(self): """ return get_naif_keyword(self, 'pixel2focal_x', 'INS{}_TRANSX'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_TRANSX'.format(self.ikid), None) @property def pixel2focal_y(self): @@ -486,7 +481,6 @@ def pixel2focal_y(self): """ return get_naif_keyword(self, 'pixel2focal_y', 'INS{}_TRANSY'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_TRANSY'.format(self.ikid), None) @property def focal_length(self): @@ -504,7 +498,6 @@ def focal_length(self): """ return get_naif_keyword(self, 'focal_length', 'INS{}_FOCAL_LENGTH'.format(self.ikid)) - #return self.naif_keywords.get('INS{}_FOCAL_LENGTH'.format(self.ikid), None) @property def target_body_radii(self): From af439947c9f162e5b0cd98c37b1c3f1af3a790bf Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 14:15:14 -0700 Subject: [PATCH 6/8] cassini, ideal naif_keyword error --- ale/drivers/co_drivers.py | 4 +++- ale/drivers/isis_ideal_drivers.py | 17 +++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ale/drivers/co_drivers.py b/ale/drivers/co_drivers.py index 94fe3e61e..752182141 100644 --- a/ale/drivers/co_drivers.py +++ b/ale/drivers/co_drivers.py @@ -8,6 +8,7 @@ from ale.base import Driver, WrongInstrumentException from ale.base.data_naif import NaifSpice from ale.base.data_isis import IsisSpice +from ale.base.data_isis import get_naif_keyword from ale.base.label_pds3 import Pds3Label from ale.base.label_isis import IsisLabel from ale.base.type_distortion import RadialDistortion, NoDistortion @@ -829,4 +830,5 @@ def focal_length(self): The focal length in millimeters """ filters = self.label["IsisCube"]["BandBin"]['FilterName'].split("/") - return self.naif_keywords.get('INS{}_{}_{}_FOCAL_LENGTH'.format(self.ikid, filters[0], filters[1]), None) + return get_naif_keyword(self, 'focal_length', 'INS{}_{}_{}_FOCAL_LENGTH'.format(self.ikid, filters[0], filters[1])) + #return self.naif_keywords.get('INS{}_{}_{}_FOCAL_LENGTH'.format(self.ikid, filters[0], filters[1]), None) diff --git a/ale/drivers/isis_ideal_drivers.py b/ale/drivers/isis_ideal_drivers.py index 2e62d0654..b6fa7f50d 100644 --- a/ale/drivers/isis_ideal_drivers.py +++ b/ale/drivers/isis_ideal_drivers.py @@ -1,4 +1,5 @@ from ale.base.data_isis import IsisSpice +from ale.base.data_isis import get_naif_keyword from ale.base.label_isis import IsisLabel from ale.base import Driver, WrongInstrumentException from ale.base.type_sensor import LineScanner @@ -129,7 +130,8 @@ def pixel2focal_x(self): : list detector to focal plane x """ - return self.naif_keywords.get('IDEAL_TRANSX') + return get_naif_keyword(self, 'pixel2focal_x', 'IDEAL_TRANSX') + #return self.naif_keywords.get('IDEAL_TRANSX') @property @@ -142,7 +144,8 @@ def pixel2focal_y(self): : list detector to focal plane y """ - return self.naif_keywords.get('IDEAL_TRANSY') + return get_naif_keyword(self, 'pixel2focal_y', 'IDEAL_TRANSY') + #return self.naif_keywords.get('IDEAL_TRANSY') @property @@ -155,8 +158,8 @@ def focal2pixel_lines(self): : list focal plane to detector lines """ - - return self.naif_keywords.get('IDEAL_TRANSL') + return get_naif_keyword(self, 'focal2pixel_lines', 'IDEAL_TRANSL') + #return self.naif_keywords.get('IDEAL_TRANSL') @property @@ -169,7 +172,8 @@ def focal2pixel_samples(self): : list focal plane to detector samples """ - return self.naif_keywords.get('IDEAL_TRANSS') + return get_naif_keyword(self, 'focal2pixel_samples', 'IDEAL_TRANSS') + #return self.naif_keywords.get('IDEAL_TRANSS') @property def focal_length(self): @@ -183,7 +187,8 @@ def focal_length(self): float : The focal length in millimeters """ - return self.naif_keywords.get('IDEAL_FOCAL_LENGTH', None) + return get_naif_keyword(self, 'focal_length', 'IDEAL_FOCAL_LENGTH') + #return self.naif_keywords.get('IDEAL_FOCAL_LENGTH', None) @property def detector_center_sample(self): From ba4aba5316d08f782e32311ed0934671e589f45a Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 14:19:01 -0700 Subject: [PATCH 7/8] rm old naifKeywd code --- ale/drivers/co_drivers.py | 1 - ale/drivers/isis_ideal_drivers.py | 5 ----- 2 files changed, 6 deletions(-) diff --git a/ale/drivers/co_drivers.py b/ale/drivers/co_drivers.py index 752182141..b0130d2b6 100644 --- a/ale/drivers/co_drivers.py +++ b/ale/drivers/co_drivers.py @@ -831,4 +831,3 @@ def focal_length(self): """ filters = self.label["IsisCube"]["BandBin"]['FilterName'].split("/") return get_naif_keyword(self, 'focal_length', 'INS{}_{}_{}_FOCAL_LENGTH'.format(self.ikid, filters[0], filters[1])) - #return self.naif_keywords.get('INS{}_{}_{}_FOCAL_LENGTH'.format(self.ikid, filters[0], filters[1]), None) diff --git a/ale/drivers/isis_ideal_drivers.py b/ale/drivers/isis_ideal_drivers.py index b6fa7f50d..ea35a1313 100644 --- a/ale/drivers/isis_ideal_drivers.py +++ b/ale/drivers/isis_ideal_drivers.py @@ -131,7 +131,6 @@ def pixel2focal_x(self): detector to focal plane x """ return get_naif_keyword(self, 'pixel2focal_x', 'IDEAL_TRANSX') - #return self.naif_keywords.get('IDEAL_TRANSX') @property @@ -145,7 +144,6 @@ def pixel2focal_y(self): detector to focal plane y """ return get_naif_keyword(self, 'pixel2focal_y', 'IDEAL_TRANSY') - #return self.naif_keywords.get('IDEAL_TRANSY') @property @@ -159,7 +157,6 @@ def focal2pixel_lines(self): focal plane to detector lines """ return get_naif_keyword(self, 'focal2pixel_lines', 'IDEAL_TRANSL') - #return self.naif_keywords.get('IDEAL_TRANSL') @property @@ -173,7 +170,6 @@ def focal2pixel_samples(self): focal plane to detector samples """ return get_naif_keyword(self, 'focal2pixel_samples', 'IDEAL_TRANSS') - #return self.naif_keywords.get('IDEAL_TRANSS') @property def focal_length(self): @@ -188,7 +184,6 @@ def focal_length(self): The focal length in millimeters """ return get_naif_keyword(self, 'focal_length', 'IDEAL_FOCAL_LENGTH') - #return self.naif_keywords.get('IDEAL_FOCAL_LENGTH', None) @property def detector_center_sample(self): From 386e6d1682e6eedda4d47aba8bf5fcb401912586 Mon Sep 17 00:00:00 2001 From: Jacob Cain Date: Wed, 1 Apr 2026 14:58:13 -0700 Subject: [PATCH 8/8] lro use get_naif_keyword method --- ale/drivers/lro_drivers.py | 47 ++++++++------------------------------ 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/ale/drivers/lro_drivers.py b/ale/drivers/lro_drivers.py index be8e5fa57..ee95fb91d 100644 --- a/ale/drivers/lro_drivers.py +++ b/ale/drivers/lro_drivers.py @@ -6,6 +6,7 @@ from ale.base import Driver, WrongInstrumentException from ale.base.data_naif import NaifSpice from ale.base.data_isis import IsisSpice +from ale.base.data_isis import get_naif_keyword from ale.base.label_pds3 import Pds3Label from ale.base.label_isis import IsisLabel from ale.base.type_sensor import LineScanner, Radar, PushFrame @@ -595,11 +596,7 @@ def odtk(self): : list Radial distortion coefficients. There is only one coefficient for LROC NAC l/r """ - key = 'INS{}_OD_K'.format(self.ikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse the distortion model coefficients using key: ' + key) - return [ans] + return get_naif_keyword(self, 'odtk', 'INS{}_OD_K'.format(self.ikid)) @property def detector_center_sample(self): @@ -1005,13 +1002,9 @@ def odtk(self): : list Radial distortion coefficients. """ - key = 'INS{}_OD_K'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse the distortion model coefficients using key: ' + key) - - ans = [x * -1 for x in ans] - return ans + val = get_naif_keyword(self, 'odtk', 'INS{}_OD_K'.format(self.fikid)) + val = [x * -1 for x in val] + return val @property def framelet_height(self): @@ -1031,11 +1024,7 @@ def pixel2focal_x(self): : list detector to focal plane x """ - key = 'INS{}_TRANSX'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse detector to focal plane x using key: ' + key) - return ans + return get_naif_keyword(self, 'pixel2focal_x', 'INS{}_TRANSX'.format(self.fikid)); @property def pixel2focal_y(self): @@ -1047,11 +1036,7 @@ def pixel2focal_y(self): : list detector to focal plane y """ - key = 'INS{}_TRANSY'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse detector to focal plane y using key: ' + key) - return ans + return get_naif_keyword(self, 'pixel2focal_y', 'INS{}_TRANSY'.format(self.fikid)) @property def focal_length(self): @@ -1067,11 +1052,7 @@ def focal_length(self): float : The focal length in millimeters """ - key = 'INS{}_FOCAL_LENGTH'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse the focal length using key: ' + key) - return ans + return get_naif_keyword(self, 'focal_length', 'INS{}_FOCAL_LENGTH'.format(self.fikid)) @property def detector_center_sample(self): @@ -1085,11 +1066,7 @@ def detector_center_sample(self): list : The center of the CCD formatted as line, sample """ - key = 'INS{}_BORESIGHT_SAMPLE'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse the detector center sample using key: ' + key) - return ans + return get_naif_keyword(self, 'detector_center_sample', 'INS{}_BORESIGHT_SAMPLE'.format(self.fikid)) @property def detector_center_line(self): @@ -1103,11 +1080,7 @@ def detector_center_line(self): list : The center of the CCD formatted as line, sample """ - key = 'INS{}_BORESIGHT_LINE'.format(self.fikid) - ans = self.naif_keywords.get(key, None) - if ans is None: - raise Exception('Could not parse the detector center line using key: ' + key) - return ans + return get_naif_keyword(self, 'detector_center_sample', 'INS{}_BORESIGHT_LINE'.format(self.fikid)) class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, RadialDistortion, Driver): """