Loading ale/base/data_naif.py +69 −3 Original line number Diff line number Diff line import spiceypy as spice import numpy as np from ale.base.type_sensor import Framer from ale.transformation import FrameNode from ale.rotation import TimeDependentRotation class NaifSpice(): def __enter__(self): Loading Loading @@ -74,7 +76,10 @@ class NaifSpice(): @property def target_frame_id(self): return spice.gipool('BODY_FRAME_CODE', 0, 1) frame_id, frame_name, found = spice.cidfrm(self.target_id) if not found: raise ValueError("No reference frame could be found for target ID {}.".format(self.target_id)) return frame_id @property def sensor_frame_id(self): Loading Loading @@ -150,10 +155,71 @@ class NaifSpice(): @property def frame_chain(self): pass """ Return the root node of the rotation frame tree/chain. The root node is the J2000 reference frame. The other nodes in the tree can be accessed via the methods in the FrameNode class. This property expects the ephemeris_time property/attribute to be defined. It should be a list of the ephemeris seconds past the J2000 epoch for each exposure in the image. Returns ------- FrameNode The root node of the frame tree. This will always be the J2000 reference frame. """ if not hasattr(self, '_root_frame'): j2000_id = 1 #J2000 is our root reference frame self._root_frame = FrameNode(j2000_id) sensor_quats = np.zeros((len(self.ephemeris_time), 4)) sensor_times = np.array(self.ephemeris_time) body_quats = np.zeros((len(self.ephemeris_time), 4)) body_times = np.array(self.ephemeris_time) for i, time in enumerate(self.ephemeris_time): sensor2j2000 = spice.pxform( self.sensor_frame_id, j2000_id, time) q_sensor = spice.m2q(sensor2j2000) sensor_quats[i,:3] = q_sensor[1:] sensor_quats[i,3] = q_sensor[0] body2j2000 = spice.pxform( self.target_frame_id, j2000_id, time) q_body = spice.m2q(body2j2000) body_quats[i,:3] = q_body[1:] body_quats[i,3] = q_body[0] sensor2j2000_rot = TimeDependentRotation( sensor_quats, sensor_times, self.sensor_frame_id, j2000_id ) sensor_node = FrameNode( self.sensor_frame_id, parent=self._root_frame, rotation=sensor2j2000_rot) body2j2000_rot = TimeDependentRotation( body_quats, body_times, self.target_frame_id, j2000_id ) body_node = FrameNode( self.target_frame_id, parent=self._root_frame, rotation=body2j2000_rot) return self._root_frame @property def _sensor_orientation(self): def sensor_orientation(self): if not hasattr(self, '_orientation'): ephem = self.ephemeris_time Loading tests/pytests/conftest.py +3 −1 Original line number Diff line number Diff line Loading @@ -20,13 +20,15 @@ class SimpleSpice(): def unload(self, *args): return def pxform(self, *args): return return np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) def m2q(self, *args): return np.asarray([1,2,3,4]) def bodn2c(self, *args): return "SPACE" def sct2e(self, *args): return 0.1 def cidfrm(self, *args): return (2000, "Test_Body_Frame", True) def get_mockkernels(self, *args): return "some_metakernel" tests/pytests/test_data_naif.py +15 −1 Original line number Diff line number Diff line Loading @@ -15,9 +15,20 @@ def test_naif_data(): naif_data = data_naif.NaifSpice() naif_data.instrument_id = "INSTRUMENT" naif_data.target_name = "TARGET" naif_data.ephemeris_time = [0, 1] return naif_data def test_frame_chain(test_naif_data): j2000 = test_naif_data.frame_chain assert j2000.parent == None assert j2000.id == 1 assert len(j2000.children) == 2 for child in j2000.children: assert child.parent == j2000 np.testing.assert_equal(child.rotation.times, np.array([0, 1])) assert child.rotation.quats.shape == (2, 4) def test_target_id(test_naif_data): assert test_naif_data.target_id == -12345 Loading @@ -29,10 +40,13 @@ def test_radii(test_naif_data): def test_naif_keywords(test_naif_data): np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY-12345_RADII'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY_FRAME_CODE'], np.arange(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY_FRAME_CODE'], 2000) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_PIXEL_SIZE'], (0.001)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_ITRANSL'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_ITRANSS'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_FOCAL_LENGTH'], np.ones(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_BORESIGHT_LINE'], np.ones(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_BORESIGHT_SAMPLE'], np.ones(1)) def test_target_frame_id(test_naif_data): assert test_naif_data.target_frame_id == 2000 Loading
ale/base/data_naif.py +69 −3 Original line number Diff line number Diff line import spiceypy as spice import numpy as np from ale.base.type_sensor import Framer from ale.transformation import FrameNode from ale.rotation import TimeDependentRotation class NaifSpice(): def __enter__(self): Loading Loading @@ -74,7 +76,10 @@ class NaifSpice(): @property def target_frame_id(self): return spice.gipool('BODY_FRAME_CODE', 0, 1) frame_id, frame_name, found = spice.cidfrm(self.target_id) if not found: raise ValueError("No reference frame could be found for target ID {}.".format(self.target_id)) return frame_id @property def sensor_frame_id(self): Loading Loading @@ -150,10 +155,71 @@ class NaifSpice(): @property def frame_chain(self): pass """ Return the root node of the rotation frame tree/chain. The root node is the J2000 reference frame. The other nodes in the tree can be accessed via the methods in the FrameNode class. This property expects the ephemeris_time property/attribute to be defined. It should be a list of the ephemeris seconds past the J2000 epoch for each exposure in the image. Returns ------- FrameNode The root node of the frame tree. This will always be the J2000 reference frame. """ if not hasattr(self, '_root_frame'): j2000_id = 1 #J2000 is our root reference frame self._root_frame = FrameNode(j2000_id) sensor_quats = np.zeros((len(self.ephemeris_time), 4)) sensor_times = np.array(self.ephemeris_time) body_quats = np.zeros((len(self.ephemeris_time), 4)) body_times = np.array(self.ephemeris_time) for i, time in enumerate(self.ephemeris_time): sensor2j2000 = spice.pxform( self.sensor_frame_id, j2000_id, time) q_sensor = spice.m2q(sensor2j2000) sensor_quats[i,:3] = q_sensor[1:] sensor_quats[i,3] = q_sensor[0] body2j2000 = spice.pxform( self.target_frame_id, j2000_id, time) q_body = spice.m2q(body2j2000) body_quats[i,:3] = q_body[1:] body_quats[i,3] = q_body[0] sensor2j2000_rot = TimeDependentRotation( sensor_quats, sensor_times, self.sensor_frame_id, j2000_id ) sensor_node = FrameNode( self.sensor_frame_id, parent=self._root_frame, rotation=sensor2j2000_rot) body2j2000_rot = TimeDependentRotation( body_quats, body_times, self.target_frame_id, j2000_id ) body_node = FrameNode( self.target_frame_id, parent=self._root_frame, rotation=body2j2000_rot) return self._root_frame @property def _sensor_orientation(self): def sensor_orientation(self): if not hasattr(self, '_orientation'): ephem = self.ephemeris_time Loading
tests/pytests/conftest.py +3 −1 Original line number Diff line number Diff line Loading @@ -20,13 +20,15 @@ class SimpleSpice(): def unload(self, *args): return def pxform(self, *args): return return np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) def m2q(self, *args): return np.asarray([1,2,3,4]) def bodn2c(self, *args): return "SPACE" def sct2e(self, *args): return 0.1 def cidfrm(self, *args): return (2000, "Test_Body_Frame", True) def get_mockkernels(self, *args): return "some_metakernel"
tests/pytests/test_data_naif.py +15 −1 Original line number Diff line number Diff line Loading @@ -15,9 +15,20 @@ def test_naif_data(): naif_data = data_naif.NaifSpice() naif_data.instrument_id = "INSTRUMENT" naif_data.target_name = "TARGET" naif_data.ephemeris_time = [0, 1] return naif_data def test_frame_chain(test_naif_data): j2000 = test_naif_data.frame_chain assert j2000.parent == None assert j2000.id == 1 assert len(j2000.children) == 2 for child in j2000.children: assert child.parent == j2000 np.testing.assert_equal(child.rotation.times, np.array([0, 1])) assert child.rotation.quats.shape == (2, 4) def test_target_id(test_naif_data): assert test_naif_data.target_id == -12345 Loading @@ -29,10 +40,13 @@ def test_radii(test_naif_data): def test_naif_keywords(test_naif_data): np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY-12345_RADII'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY_FRAME_CODE'], np.arange(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['BODY_FRAME_CODE'], 2000) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_PIXEL_SIZE'], (0.001)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_ITRANSL'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_ITRANSS'], np.ones(3)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_FOCAL_LENGTH'], np.ones(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_BORESIGHT_LINE'], np.ones(1)) np.testing.assert_equal(test_naif_data.isis_naif_keywords['INS-12345_BORESIGHT_SAMPLE'], np.ones(1)) def test_target_frame_id(test_naif_data): assert test_naif_data.target_frame_id == 2000