Skip to content
Snippets Groups Projects
Commit 6d3f2b73 authored by Jesse Mapel's avatar Jesse Mapel Committed by Kristin
Browse files

Added ISIS special NAIF keywords (#271)

* Added ISIS special NAIF keywords

* Better variable name

* Moved obs and targ to temp vars

* Added proper observer and target swapping code

* Updated from upstream
parent 89cf4c57
No related branches found
No related tags found
No related merge requests found
...@@ -46,11 +46,12 @@ class NaifSpice(): ...@@ -46,11 +46,12 @@ class NaifSpice():
def light_time_correction(self): def light_time_correction(self):
""" """
Returns the type of light time correciton and abberation correction to 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), This searches for the value of the NAIF keyword INS<ikid>_LIGHTTIME_CORRECTION.
concrete drivers should override this if they need to either not use If the keyword is not defined, then this defaults to light time
light time correction or use a different type of light time correction. correction and abberation correction (LT+S).
Returns Returns
------- -------
...@@ -59,6 +60,9 @@ class NaifSpice(): ...@@ -59,6 +60,9 @@ class NaifSpice():
See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html See https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/abcorr.html
for the different options available. for the different options available.
""" """
try:
return spice.gcpool('INS{}_LIGHTTIME_CORRECTION'.format(self.ikid), 0, 1)[0]
except:
return 'LT+S' return 'LT+S'
@property @property
...@@ -318,21 +322,32 @@ class NaifSpice(): ...@@ -318,21 +322,32 @@ class NaifSpice():
pos = [] pos = []
vel = [] 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: for time in ephem:
# spkezr returns a vector from the observer's location to the aberration-corrected # spkezr returns a vector from the observer's location to the aberration-corrected
# location of the target. For more information, see: # location of the target. For more information, see:
# https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/spicelib/spkezr.html # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/spicelib/spkezr.html
state, _ = spice.spkezr(self.target_name, state, _ = spice.spkezr(target,
time, time,
self.reference_frame, self.reference_frame,
self.light_time_correction, self.light_time_correction,
self.spacecraft_name,) observer)
if self.swap_observer_target:
pos.append(state[:3]) pos.append(state[:3])
vel.append(state[3:]) vel.append(state[3:])
# By default, spice works in km, and the vector returned by spkezr points the opposite else:
# direction to what ALE needs, so it must be multiplied by (-1) pos.append(-state[:3])
self._position = np.asarray([p * -1000 for p in pos]) vel.append(-state[3:])
self._velocity = np.asarray([v * -1000 for v in vel])
# 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 return self._position, self._velocity, self.ephemeris_time
@property @property
...@@ -427,6 +442,39 @@ class NaifSpice(): ...@@ -427,6 +442,39 @@ class NaifSpice():
return float(spice.gdpool('INS{}_BORESIGHT_LINE'.format(self.ikid), 0, 1)[0]) 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 @property
def isis_naif_keywords(self): def isis_naif_keywords(self):
""" """
......
...@@ -83,6 +83,15 @@ class test_data_naif(unittest.TestCase): ...@@ -83,6 +83,15 @@ class test_data_naif(unittest.TestCase):
def test_detector_center_line(self): def test_detector_center_line(self):
assert self.driver.detector_center_line == 0.430442527 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): def test_sun_position(self):
sun_positions, sun_velocities, times = self.driver.sun_position sun_positions, sun_velocities, times = self.driver.sun_position
assert len(sun_positions) == 1 assert len(sun_positions) == 1
...@@ -91,3 +100,26 @@ class test_data_naif(unittest.TestCase): ...@@ -91,3 +100,26 @@ class test_data_naif(unittest.TestCase):
np.testing.assert_allclose(sun_velocities[0], [9883868.06162645, 8989183.29614645, 881.9339912834714]) np.testing.assert_allclose(sun_velocities[0], [9883868.06162645, 8989183.29614645, 881.9339912834714])
assert len(times) == 1 assert len(times) == 1
np.testing.assert_allclose(times[0], 297088762.61698407) 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)
...@@ -108,12 +108,12 @@ def test_load(test_kernels): ...@@ -108,12 +108,12 @@ def test_load(test_kernels):
[ 193824.32093681, 210061.95495794, -1767367.56104995], [ 193824.32093681, 210061.95495794, -1767367.56104995],
[ 193267.90484827, 209421.16305764, -1767500.49120063], [ 193267.90484827, 209421.16305764, -1767500.49120063],
[ 192711.44397634, 208780.32318594, -1767633.01318365]]), [ 192711.44397634, 208780.32318594, -1767633.01318365]]),
'velocities': np.array([[-1069.71225785, -1231.97438089, -258.37880523], 'velocities': np.array([[-1069.70946002, -1231.97108635, -258.37361381],
[-1069.80205939, -1232.06556741, -257.5939851 ], [-1069.79925825, -1232.06226912, -257.58879787],
[-1069.89161639, -1232.15647191, -256.80910187], [-1069.88881194, -1232.15316986, -256.80391882],
[-1069.98092881, -1232.24709434, -256.02415587], [-1069.97812106, -1232.24378854, -256.01897702],
[-1070.06999666, -1232.33743471, -255.2391471 ], [-1070.06718562, -1232.33412517, -255.23397236],
[-1070.15881991, -1232.42749298, -254.4540759 ]]), [-1070.15600557, -1232.42417969, -254.44890536]]),
'unit': 'm'}, 'unit': 'm'},
'sun_position': { 'sun_position': {
'positions': np.array([[9.50465237e+10, 1.15903815e+11, 3.78729685e+09]]), 'positions': np.array([[9.50465237e+10, 1.15903815e+11, 3.78729685e+09]]),
......
...@@ -28,8 +28,8 @@ def usgscsm_compare_dict(): ...@@ -28,8 +28,8 @@ def usgscsm_compare_dict():
'semiminor': 2439.4, 'semiminor': 2439.4,
'unit': 'km'}, 'unit': 'km'},
'sensor_position': { 'sensor_position': {
'positions': np.array([[ -629496.48621395, -1582946.00913133, 1783952.64031042]]), 'positions': np.array([[-629657.4559945846, -1583350.7374122413, 1784408.773440049]]),
'velocities': np.array([[1732.18666313, 2502.76825324, 2412.65232223]]), 'velocities': np.array([[1732.8734290653545, 2504.0213215928925, 2412.578186708735]]),
'unit': 'm'}, 'unit': 'm'},
'sun_position': { 'sun_position': {
'positions': np.array([[-4.68946673e+10, -5.36158427e+08, 2.71167863e+07]]), 'positions': np.array([[-4.68946673e+10, -5.36158427e+08, 2.71167863e+07]]),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment