Loading ale/base/data_naif.py +64 −16 Original line number Diff line number Diff line Loading @@ -46,11 +46,12 @@ class NaifSpice(): def light_time_correction(self): """ Returns the type of light time correciton and abberation correction to use in NAIF calls. use in NAIF calls. Expects ikid to be defined. This must be the integer Naif id code of the instrument. This defaults to light time correction and abberation correction (LT+S), concrete drivers should override this if they need to either not use light time correction or use a different type of light time correction. This searches for the value of the NAIF keyword INS<ikid>_LIGHTTIME_CORRECTION. If the keyword is not defined, then this defaults to light time correction and abberation correction (LT+S). Returns ------- Loading @@ -59,6 +60,9 @@ class NaifSpice(): See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html for the different options available. """ try: return spice.gcpool('INS{}_LIGHTTIME_CORRECTION'.format(self.ikid), 0, 1)[0] except: return 'LT+S' @property Loading Loading @@ -318,21 +322,32 @@ class NaifSpice(): pos = [] vel = [] target = self.target_name observer = self.spacecraft_name # Check for ISIS flag to fix target and observer swapping if self.swap_observer_target: target = self.spacecraft_name observer = self.target_name for time in ephem: # spkezr returns a vector from the observer's location to the aberration-corrected # location of the target. For more information, see: # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/spicelib/spkezr.html state, _ = spice.spkezr(self.target_name, state, _ = spice.spkezr(target, time, self.reference_frame, self.light_time_correction, self.spacecraft_name,) observer) if self.swap_observer_target: pos.append(state[:3]) vel.append(state[3:]) # By default, spice works in km, and the vector returned by spkezr points the opposite # direction to what ALE needs, so it must be multiplied by (-1) self._position = np.asarray([p * -1000 for p in pos]) self._velocity = np.asarray([v * -1000 for v in vel]) else: pos.append(-state[:3]) vel.append(-state[3:]) # By default, SPICE works in km, so convert to m self._position = [p * 1000 for p in pos] self._velocity = [v * 1000 for v in vel] return self._position, self._velocity, self.ephemeris_time @property Loading Loading @@ -427,6 +442,39 @@ class NaifSpice(): return float(spice.gdpool('INS{}_BORESIGHT_LINE'.format(self.ikid), 0, 1)[0]) @property def swap_observer_target(self): """ Returns if the observer and target should be swapped when determining the sensor state relative to the target. This is defined by a keyword in ISIS IAKs. If the keyword is not defined in any loaded kernels then False is returned. Expects ikid to be defined. This should be an integer containing the Naif Id code of the instrument. """ try: swap = spice.gcpool('INS{}_SWAP_OBSERVER_TARGET'.format(self.ikid), 0, 1)[0] return swap.upper() == "TRUE" except: return False @property def correct_lt_to_surface(self): """ Returns if light time correction should be made to the surface instead of to the center of the body. This is defined by a keyword in ISIS IAKs. If the keyword is not defined in any loaded kernels then False is returned. Expects ikid to be defined. This should be an integer containing the Naif Id code of the instrument. """ try: surface_correct = spice.gcpool('INS{}_LT_SURFACE_CORRECT'.format(self.ikid), 0, 1)[0] return surface_correct.upper() == "TRUE" except: return False @property def isis_naif_keywords(self): """ Loading tests/pytests/test_data_naif.py +32 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,15 @@ class test_data_naif(unittest.TestCase): def test_detector_center_line(self): assert self.driver.detector_center_line == 0.430442527 def test_swap_observer_target(self): assert not self.driver.swap_observer_target def test_light_time_correction(self): assert self.driver.light_time_correction == "LT+S" def test_correct_lt_to_surface(self): assert not self.driver.correct_lt_to_surface def test_sun_position(self): sun_positions, sun_velocities, times = self.driver.sun_position assert len(sun_positions) == 1 Loading @@ -91,3 +100,26 @@ class test_data_naif(unittest.TestCase): np.testing.assert_allclose(sun_velocities[0], [9883868.06162645, 8989183.29614645, 881.9339912834714]) assert len(times) == 1 np.testing.assert_allclose(times[0], 297088762.61698407) def test_light_time_correction_keyword(): with patch('ale.base.data_naif.spice.gcpool', return_value=['NONE']) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().light_time_correction == 'NONE' gcpool.assert_called_with('INS-12345_LIGHTTIME_CORRECTION', 0, 1) @pytest.mark.parametrize(("key_val, return_val"), [(['TRUE'], True), (['FALSE'], False)]) def test_swap_observer_target_keyword(key_val, return_val): with patch('ale.base.data_naif.spice.gcpool', return_value=key_val) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().swap_observer_target == return_val gcpool.assert_called_with('INS-12345_SWAP_OBSERVER_TARGET', 0, 1) @pytest.mark.parametrize(("key_val, return_val"), [(['TRUE'], True), (['FALSE'], False)]) def test_correct_lt_to_surface_keyword(key_val, return_val): with patch('ale.base.data_naif.spice.gcpool', return_value=key_val) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().correct_lt_to_surface == return_val gcpool.assert_called_with('INS-12345_LT_SURFACE_CORRECT', 0, 1) tests/pytests/test_kaguya_drivers.py +6 −6 Original line number Diff line number Diff line Loading @@ -108,12 +108,12 @@ def test_load(test_kernels): [ 193824.32093681, 210061.95495794, -1767367.56104995], [ 193267.90484827, 209421.16305764, -1767500.49120063], [ 192711.44397634, 208780.32318594, -1767633.01318365]]), 'velocities': np.array([[-1069.71225785, -1231.97438089, -258.37880523], [-1069.80205939, -1232.06556741, -257.5939851 ], [-1069.89161639, -1232.15647191, -256.80910187], [-1069.98092881, -1232.24709434, -256.02415587], [-1070.06999666, -1232.33743471, -255.2391471 ], [-1070.15881991, -1232.42749298, -254.4540759 ]]), 'velocities': np.array([[-1069.70946002, -1231.97108635, -258.37361381], [-1069.79925825, -1232.06226912, -257.58879787], [-1069.88881194, -1232.15316986, -256.80391882], [-1069.97812106, -1232.24378854, -256.01897702], [-1070.06718562, -1232.33412517, -255.23397236], [-1070.15600557, -1232.42417969, -254.44890536]]), 'unit': 'm'}, 'sun_position': { 'positions': np.array([[9.50465237e+10, 1.15903815e+11, 3.78729685e+09]]), Loading tests/pytests/test_mdis_drivers.py +2 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ def usgscsm_compare_dict(): 'semiminor': 2439.4, 'unit': 'km'}, 'sensor_position': { 'positions': np.array([[ -629496.48621395, -1582946.00913133, 1783952.64031042]]), 'velocities': np.array([[1732.18666313, 2502.76825324, 2412.65232223]]), 'positions': np.array([[-629657.4559945846, -1583350.7374122413, 1784408.773440049]]), 'velocities': np.array([[1732.8734290653545, 2504.0213215928925, 2412.578186708735]]), 'unit': 'm'}, 'sun_position': { 'positions': np.array([[-4.68946673e+10, -5.36158427e+08, 2.71167863e+07]]), Loading Loading
ale/base/data_naif.py +64 −16 Original line number Diff line number Diff line Loading @@ -46,11 +46,12 @@ class NaifSpice(): def light_time_correction(self): """ Returns the type of light time correciton and abberation correction to use in NAIF calls. use in NAIF calls. Expects ikid to be defined. This must be the integer Naif id code of the instrument. This defaults to light time correction and abberation correction (LT+S), concrete drivers should override this if they need to either not use light time correction or use a different type of light time correction. This searches for the value of the NAIF keyword INS<ikid>_LIGHTTIME_CORRECTION. If the keyword is not defined, then this defaults to light time correction and abberation correction (LT+S). Returns ------- Loading @@ -59,6 +60,9 @@ class NaifSpice(): See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html for the different options available. """ try: return spice.gcpool('INS{}_LIGHTTIME_CORRECTION'.format(self.ikid), 0, 1)[0] except: return 'LT+S' @property Loading Loading @@ -318,21 +322,32 @@ class NaifSpice(): pos = [] vel = [] target = self.target_name observer = self.spacecraft_name # Check for ISIS flag to fix target and observer swapping if self.swap_observer_target: target = self.spacecraft_name observer = self.target_name for time in ephem: # spkezr returns a vector from the observer's location to the aberration-corrected # location of the target. For more information, see: # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/spicelib/spkezr.html state, _ = spice.spkezr(self.target_name, state, _ = spice.spkezr(target, time, self.reference_frame, self.light_time_correction, self.spacecraft_name,) observer) if self.swap_observer_target: pos.append(state[:3]) vel.append(state[3:]) # By default, spice works in km, and the vector returned by spkezr points the opposite # direction to what ALE needs, so it must be multiplied by (-1) self._position = np.asarray([p * -1000 for p in pos]) self._velocity = np.asarray([v * -1000 for v in vel]) else: pos.append(-state[:3]) vel.append(-state[3:]) # By default, SPICE works in km, so convert to m self._position = [p * 1000 for p in pos] self._velocity = [v * 1000 for v in vel] return self._position, self._velocity, self.ephemeris_time @property Loading Loading @@ -427,6 +442,39 @@ class NaifSpice(): return float(spice.gdpool('INS{}_BORESIGHT_LINE'.format(self.ikid), 0, 1)[0]) @property def swap_observer_target(self): """ Returns if the observer and target should be swapped when determining the sensor state relative to the target. This is defined by a keyword in ISIS IAKs. If the keyword is not defined in any loaded kernels then False is returned. Expects ikid to be defined. This should be an integer containing the Naif Id code of the instrument. """ try: swap = spice.gcpool('INS{}_SWAP_OBSERVER_TARGET'.format(self.ikid), 0, 1)[0] return swap.upper() == "TRUE" except: return False @property def correct_lt_to_surface(self): """ Returns if light time correction should be made to the surface instead of to the center of the body. This is defined by a keyword in ISIS IAKs. If the keyword is not defined in any loaded kernels then False is returned. Expects ikid to be defined. This should be an integer containing the Naif Id code of the instrument. """ try: surface_correct = spice.gcpool('INS{}_LT_SURFACE_CORRECT'.format(self.ikid), 0, 1)[0] return surface_correct.upper() == "TRUE" except: return False @property def isis_naif_keywords(self): """ Loading
tests/pytests/test_data_naif.py +32 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,15 @@ class test_data_naif(unittest.TestCase): def test_detector_center_line(self): assert self.driver.detector_center_line == 0.430442527 def test_swap_observer_target(self): assert not self.driver.swap_observer_target def test_light_time_correction(self): assert self.driver.light_time_correction == "LT+S" def test_correct_lt_to_surface(self): assert not self.driver.correct_lt_to_surface def test_sun_position(self): sun_positions, sun_velocities, times = self.driver.sun_position assert len(sun_positions) == 1 Loading @@ -91,3 +100,26 @@ class test_data_naif(unittest.TestCase): np.testing.assert_allclose(sun_velocities[0], [9883868.06162645, 8989183.29614645, 881.9339912834714]) assert len(times) == 1 np.testing.assert_allclose(times[0], 297088762.61698407) def test_light_time_correction_keyword(): with patch('ale.base.data_naif.spice.gcpool', return_value=['NONE']) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().light_time_correction == 'NONE' gcpool.assert_called_with('INS-12345_LIGHTTIME_CORRECTION', 0, 1) @pytest.mark.parametrize(("key_val, return_val"), [(['TRUE'], True), (['FALSE'], False)]) def test_swap_observer_target_keyword(key_val, return_val): with patch('ale.base.data_naif.spice.gcpool', return_value=key_val) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().swap_observer_target == return_val gcpool.assert_called_with('INS-12345_SWAP_OBSERVER_TARGET', 0, 1) @pytest.mark.parametrize(("key_val, return_val"), [(['TRUE'], True), (['FALSE'], False)]) def test_correct_lt_to_surface_keyword(key_val, return_val): with patch('ale.base.data_naif.spice.gcpool', return_value=key_val) as gcpool, \ patch('ale.base.data_naif.NaifSpice.ikid', new_callable=PropertyMock) as ikid: ikid.return_value = -12345 assert NaifSpice().correct_lt_to_surface == return_val gcpool.assert_called_with('INS-12345_LT_SURFACE_CORRECT', 0, 1)
tests/pytests/test_kaguya_drivers.py +6 −6 Original line number Diff line number Diff line Loading @@ -108,12 +108,12 @@ def test_load(test_kernels): [ 193824.32093681, 210061.95495794, -1767367.56104995], [ 193267.90484827, 209421.16305764, -1767500.49120063], [ 192711.44397634, 208780.32318594, -1767633.01318365]]), 'velocities': np.array([[-1069.71225785, -1231.97438089, -258.37880523], [-1069.80205939, -1232.06556741, -257.5939851 ], [-1069.89161639, -1232.15647191, -256.80910187], [-1069.98092881, -1232.24709434, -256.02415587], [-1070.06999666, -1232.33743471, -255.2391471 ], [-1070.15881991, -1232.42749298, -254.4540759 ]]), 'velocities': np.array([[-1069.70946002, -1231.97108635, -258.37361381], [-1069.79925825, -1232.06226912, -257.58879787], [-1069.88881194, -1232.15316986, -256.80391882], [-1069.97812106, -1232.24378854, -256.01897702], [-1070.06718562, -1232.33412517, -255.23397236], [-1070.15600557, -1232.42417969, -254.44890536]]), 'unit': 'm'}, 'sun_position': { 'positions': np.array([[9.50465237e+10, 1.15903815e+11, 3.78729685e+09]]), Loading
tests/pytests/test_mdis_drivers.py +2 −2 Original line number Diff line number Diff line Loading @@ -28,8 +28,8 @@ def usgscsm_compare_dict(): 'semiminor': 2439.4, 'unit': 'km'}, 'sensor_position': { 'positions': np.array([[ -629496.48621395, -1582946.00913133, 1783952.64031042]]), 'velocities': np.array([[1732.18666313, 2502.76825324, 2412.65232223]]), 'positions': np.array([[-629657.4559945846, -1583350.7374122413, 1784408.773440049]]), 'velocities': np.array([[1732.8734290653545, 2504.0213215928925, 2412.578186708735]]), 'unit': 'm'}, 'sun_position': { 'positions': np.array([[-4.68946673e+10, -5.36158427e+08, 2.71167863e+07]]), Loading