Skip to content
Snippets Groups Projects
Select Git revision
  • 246ae894592f56f719260b86ce608dbcf26bd0d2
  • main default protected
  • Kelvinrr-patch-3
  • radius_update
  • revert-616-apollo_pan
  • vims
  • 0.10
  • Kelvinrr-patch-2
  • revert-563-minirf_fix
  • Kelvinrr-patch-1
  • 0.9
  • acpaquette-patch-3
  • acpaquette-patch-2
  • acpaquette-patch-1
  • spiceql
  • ci-coverage
  • 0.10.0
  • 0.9.1
  • 0.9.0
  • 0.8.7
  • 0.8.8
  • 0.8.6
  • 0.8.3
  • 0.8.4
  • 0.8.5
  • 0.8.2
  • 0.8.1
  • 0.8.0
  • 0.7.3
  • 0.7.2
  • 0.7.1
  • 0.7.0
  • 0.6.5
  • 0.6.4
  • 0.6.3
  • 0.6.2
36 results

test_lro_drivers.py

Blame
  • test_lro_drivers.py 17.57 KiB
    import pytest
    import numpy as np
    import os
    import unittest
    from unittest.mock import MagicMock, PropertyMock, patch
    import spiceypy as spice
    import json
    
    import ale
    from ale import util
    from ale.drivers.lro_drivers import LroLrocNacPds3LabelNaifSpiceDriver
    from ale.drivers.lro_drivers import LroLrocNacIsisLabelNaifSpiceDriver
    from ale.drivers.lro_drivers import LroLrocWacIsisLabelNaifSpiceDriver
    from ale.drivers.lro_drivers import LroLrocWacIsisLabelIsisSpiceDriver
    from ale.drivers.lro_drivers import LroMiniRfIsisLabelNaifSpiceDriver
    from ale.transformation import TimeDependentRotation
    
    from conftest import get_image, get_image_label, get_isd, get_image_kernels, convert_kernels, compare_dicts
    
    image_dict = {
        'M103595705LE': get_isd("lrolroc"),
        '03821_16N196_S1': get_isd("lrominirf"),
        'wac0000a1c4.uv.even': get_isd('lrolrocwac')
    }
    
    # LROC test kernels
    @pytest.fixture(scope="module")
    def test_kernels():
        updated_kernels = {}
        binary_kernels = {}
        for image in image_dict.keys():
            kernels = get_image_kernels(image)
            updated_kernels[image], binary_kernels[image] = convert_kernels(kernels)
        yield updated_kernels
        for kern_list in binary_kernels.values():
            for kern in kern_list:
                os.remove(kern)
    
    # Test load of LROC labels
    @pytest.mark.parametrize("label_type, kernel_type", [('isis3', 'naif'), ('isis3', 'isis')])
    #@pytest.mark.parametrize("image", image_dict.keys()) Add this when when all are supported by ale isd.
    @pytest.mark.parametrize("image", ['M103595705LE'])
    def test_load(test_kernels, label_type, image, kernel_type):
        if kernel_type == 'naif':
            label_file = get_image_label(image, label_type)
            isd_str = ale.loads(label_file, props={'kernels': test_kernels[image]})
            compare_isd = image_dict[image]
        else:
            label_file = get_image(image)
            isd_str = ale.loads(label_file)
            compare_isd = get_isd('lro_isis')
    
        isd_obj = json.loads(isd_str)
        print(json.dumps(isd_obj, indent=2))
        assert compare_dicts(isd_obj, compare_isd) == []
    
    # Test load of MiniRF labels
    def test_load_minirf(test_kernels):
        label_file = get_image_label('03821_16N196_S1', 'isis3')
        # isd_str = ale.loads(label_file, props={'kernels': test_kernels['03821_16N196_S1']}, formatter='usgscsm', verbose=True)
        isd_str = ale.loads(label_file, props={'kernels': test_kernels['03821_16N196_S1']}, verbose=True)
        isd_obj = json.loads(isd_str)
        print(json.dumps(isd_obj, indent=2))
        assert compare_dicts(isd_obj, image_dict['03821_16N196_S1']) == []
    
    # ========= Test pdslabel and naifspice driver =========
    class test_pds_naif(unittest.TestCase):
    
        def setUp(self):
            label = get_image_label('M103595705LE', 'pds3')
            self.driver = LroLrocNacPds3LabelNaifSpiceDriver(label)
    
        def test_short_mission_name(self):
            assert self.driver.short_mission_name=='lro'
    
        def test_instrument_id_left(self):
            self.driver.label['FRAME_ID'] = 'LEFT'
            assert self.driver.instrument_id == 'LRO_LROCNACL'
    
        def test_instrument_id_right(self):
            self.driver.label['FRAME_ID'] = 'RIGHT'
            assert self.driver.instrument_id == 'LRO_LROCNACR'
    
        def test_spacecraft_name(self):
            assert self.driver.spacecraft_name == 'LRO'
    
        def test_sensor_model_version(self):
            assert self.driver.sensor_model_version == 2
    
        def test_odtk(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.odtk == [1.0]
                gdpool.assert_called_with('INS-12345_OD_K', 0, 1)
    
        def test_usgscsm_distortion_model(self):
            with patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.odtk', \
                       new_callable=PropertyMock) as odtk:
                odtk.return_value = [1.0]
                distortion_model = self.driver.usgscsm_distortion_model
                assert distortion_model['lrolrocnac']['coefficients'] == [1.0]
    
        def test_ephemeris_start_time(self):
            with patch('ale.drivers.lro_drivers.spice.scs2e', return_value=5) as scs2e, \
                 patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.exposure_duration', \
                       new_callable=PropertyMock) as exposure_duration, \
                 patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.spacecraft_id', \
                       new_callable=PropertyMock) as spacecraft_id:
                exposure_duration.return_value = 0.1
                spacecraft_id.return_value = 1234
                assert self.driver.ephemeris_start_time == 107.4
                scs2e.assert_called_with(1234, "1/270649237:07208")
    
        def test_exposure_duration(self):
            with patch('ale.base.label_pds3.Pds3Label.exposure_duration', \
                       new_callable=PropertyMock) as exposure_duration:
                exposure_duration.return_value = 1
                assert self.driver.exposure_duration == 1.0045
    
        @patch('ale.transformation.FrameChain')
        @patch('ale.transformation.FrameChain.from_spice', return_value=ale.transformation.FrameChain())
        @patch('ale.transformation.FrameChain.compute_rotation', return_value=TimeDependentRotation([[0, 0, 1, 0]], [0], 0, 0))
        def test_spacecraft_direction(self, compute_rotation, from_spice, frame_chain):
            with patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.target_frame_id', \
                 new_callable=PropertyMock) as target_frame_id, \
                 patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.ephemeris_start_time', \
                 new_callable=PropertyMock) as ephemeris_start_time, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c, \
                 patch('ale.drivers.lro_drivers.spice.spkezr', return_value=[[1, 1, 1, 1, 1, 1], 0]) as spkezr, \
                 patch('ale.drivers.lro_drivers.spice.mxv', return_value=[1, 1, 1]) as mxv:
                ephemeris_start_time.return_value = 0
                assert self.driver.spacecraft_direction > 0
                bods2c.assert_called_with('LRO_SC_BUS')
                spkezr.assert_called_with(self.driver.spacecraft_name, 0, 'J2000', 'None', self.driver.target_name)
                compute_rotation.assert_called_with(1, -12345)
                np.testing.assert_array_equal(np.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]), mxv.call_args[0][0])
                np.testing.assert_array_equal(np.array([1, 1, 1]), mxv.call_args[0][1])
    
        def test_focal2pixel_lines(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=[0, 1, 0]) as gdpool, \
                 patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.ikid', \
                 new_callable=PropertyMock) as ikid, \
                 patch('ale.drivers.lro_drivers.LroLrocNacPds3LabelNaifSpiceDriver.spacecraft_direction', \
                 new_callable=PropertyMock) as spacecraft_direction:
                spacecraft_direction.return_value = -1
                np.testing.assert_array_equal(self.driver.focal2pixel_lines, [0, -1, 0])
                spacecraft_direction.return_value = 1
                np.testing.assert_array_equal(self.driver.focal2pixel_lines, [0, 1, 0])
    
    
    # ========= Test isislabel and naifspice driver =========
    class test_isis_naif(unittest.TestCase):
    
        def setUp(self):
            label = get_image_label('M103595705LE', 'isis3')
            self.driver = LroLrocNacIsisLabelNaifSpiceDriver(label)
    
        def test_short_mission_name(self):
            assert self.driver.short_mission_name == 'lro'
    
        def test_intrument_id(self):
            assert self.driver.instrument_id == 'LRO_LROCNACL'
    
        def test_usgscsm_distortion_model(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                distortion_model = self.driver.usgscsm_distortion_model
                assert distortion_model['lrolrocnac']['coefficients'] == [1.0]
                gdpool.assert_called_with('INS-12345_OD_K', 0, 1)
                bods2c.assert_called_with('LRO_LROCNACL')
    
        def test_odtk(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                 assert self.driver.odtk == [1.0]
                 gdpool.assert_called_with('INS-12345_OD_K', 0, 1)
                 bods2c.assert_called_with('LRO_LROCNACL')
    
        def test_light_time_correction(self):
            assert self.driver.light_time_correction == 'NONE'
    
        def test_detector_center_sample(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.detector_center_sample == 0.5
                gdpool.assert_called_with('INS-12345_BORESIGHT_SAMPLE', 0, 1)
                bods2c.assert_called_with('LRO_LROCNACL')
    
        def test_exposure_duration(self):
            np.testing.assert_almost_equal(self.driver.exposure_duration, .0010334296)
    
        def test_ephemeris_start_time(self):
            with patch('ale.drivers.lro_drivers.spice.scs2e', return_value=321) as scs2e:
                np.testing.assert_almost_equal(self.driver.ephemeris_start_time, 322.05823191)
                scs2e.assert_called_with(-85, '1/270649237:07208')
    
        def test_multiplicative_line_error(self):
            assert self.driver.multiplicative_line_error == 0.0045
    
        def test_additive_line_error(self):
            assert self.driver.additive_line_error == 0
    
        def test_constant_time_offset(self):
            assert self.driver.constant_time_offset == 0
    
        def test_additional_preroll(self):
            assert self.driver.additional_preroll == 1024
    
        def test_sampling_factor(self):
            assert self.driver.sampling_factor == 1
    
        @patch('ale.transformation.FrameChain')
        @patch('ale.transformation.FrameChain.from_spice', return_value=ale.transformation.FrameChain())
        @patch('ale.transformation.FrameChain.compute_rotation', return_value=TimeDependentRotation([[0, 0, 1, 0]], [0], 0, 0))
        def test_spacecraft_direction(self, compute_rotation, from_spice, frame_chain):
            with patch('ale.drivers.lro_drivers.LroLrocNacIsisLabelNaifSpiceDriver.target_frame_id', \
                 new_callable=PropertyMock) as target_frame_id, \
                 patch('ale.drivers.lro_drivers.LroLrocNacIsisLabelNaifSpiceDriver.ephemeris_start_time', \
                 new_callable=PropertyMock) as ephemeris_start_time, \
                 patch('ale.drivers.lro_drivers.spice.cidfrm', return_value=[-12345]) as cidfrm, \
                 patch('ale.drivers.lro_drivers.spice.scs2e', return_value=0) as scs2e, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c, \
                 patch('ale.drivers.lro_drivers.spice.spkezr', return_value=[[1, 1, 1, 1, 1, 1], 0]) as spkezr, \
                 patch('ale.drivers.lro_drivers.spice.mxv', return_value=[1, 1, 1]) as mxv:
                ephemeris_start_time.return_value = 0
                assert self.driver.spacecraft_direction > 0
                spkezr.assert_called_with(self.driver.spacecraft_name, 0, 'J2000', 'None', self.driver.target_name)
                compute_rotation.assert_called_with(1, -12345)
                np.testing.assert_array_equal(np.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, 1.0]]), mxv.call_args[0][0])
                np.testing.assert_array_equal(np.array([1, 1, 1]), mxv.call_args[0][1])
    
        def test_focal2pixel_lines(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=[0, 1, 0]) as gdpool, \
                 patch('ale.drivers.lro_drivers.LroLrocNacIsisLabelNaifSpiceDriver.ikid', \
                 new_callable=PropertyMock) as ikid, \
                 patch('ale.drivers.lro_drivers.LroLrocNacIsisLabelNaifSpiceDriver.spacecraft_direction', \
                 new_callable=PropertyMock) as spacecraft_direction:
                spacecraft_direction.return_value = -1
                np.testing.assert_array_equal(self.driver.focal2pixel_lines, [0, -1, 0])
                spacecraft_direction.return_value = 1
                np.testing.assert_array_equal(self.driver.focal2pixel_lines, [0, 1, 0])
    
    
    # ========= Test MiniRf isislabel and naifspice driver =========
    class test_miniRf(unittest.TestCase):
        def setUp(self):
            label = get_image_label('03821_16N196_S1', 'isis3')
            self.driver = LroMiniRfIsisLabelNaifSpiceDriver(label)
    
        def test_wavelength(self):
            np.testing.assert_almost_equal(self.driver.wavelength, 1.25963224167508e-01)
    
        def test_scaled_pixel_width(self):
            np.testing.assert_almost_equal(self.driver.scaled_pixel_width, 7.50)
    
        def test_line_exposure_duration(self):
            np.testing.assert_almost_equal(self.driver.line_exposure_duration, 4.70442147400000e-03)
    
        def test_range_conversion_coefficients(self):
            with patch('ale.drivers.lro_drivers.spice.str2et', return_value=12345) as str2et:
              assert len(self.driver.range_conversion_coefficients) == 20
    
        def test_ephmeris_start_time(self):
            with patch('ale.drivers.lro_drivers.spice.str2et', return_value=12345) as str2et:
              assert self.driver.ephemeris_start_time == 12345
    
        def test_ephmeris_stop_time(self):
            with patch('ale.drivers.lro_drivers.spice.str2et', return_value=12345) as str2et:
              assert self.driver.ephemeris_stop_time == 12345
    
    
    # ========= Test WAC isislabel and naifspice driver =========
    class test_wac_isis_naif(unittest.TestCase):
    
        def setUp(self):
            label = get_image_label('wac0000a1c4.uv.even', 'isis3')
            self.driver = LroLrocWacIsisLabelNaifSpiceDriver(label)
    
        def test_short_mission_name(self):
            assert self.driver.short_mission_name == 'lro'
    
        def test_intrument_id(self):
            assert self.driver.instrument_id == 'LRO_LROCWAC_UV'
    
        def test_ephemeris_start_time(self):
            with patch('ale.drivers.lro_drivers.spice.scs2e', return_value=321) as scs2e:
                np.testing.assert_almost_equal(self.driver.ephemeris_start_time, 321)
                scs2e.assert_called_with(-85, '1/274692469:15073')
    
        def test_detector_center_sample(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.detector_center_sample == 0.5
                gdpool.assert_called_with('INS-12345_BORESIGHT_SAMPLE', 0, 1)
                bods2c.assert_called_with('LRO_LROCWAC_UV')
    
        def test_detector_center_line(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
                 patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.detector_center_line == 0.5
                gdpool.assert_called_with('INS-12345_BORESIGHT_LINE', 0, 1)
                bods2c.assert_called_with('LRO_LROCWAC_UV')
    
        def test_odtk(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool:
                 assert self.driver.odtk == [-1.0]
                 gdpool.assert_called_with('INS-85641_OD_K', 0, 3)
    
        def test_light_time_correction(self):
            assert self.driver.light_time_correction == 'LT+S'
    
        def test_exposure_duration(self):
            np.testing.assert_almost_equal(self.driver.exposure_duration, 0.04)
    
        def test_sensor_name(self):
            assert self.driver.sensor_name == "LUNAR RECONNAISSANCE ORBITER"
    
        def test_framelets_flipped(self):
            assert self.driver.framelets_flipped == False
    
        def test_sampling_factor(self):
            assert self.driver.sampling_factor == 4
    
        def test_num_frames(self):
            assert self.driver.num_frames == 260
    
        def test_framelet_height(self):
            assert self.driver.framelet_height == 16
    
        def test_filter_number(self):
            assert self.driver.filter_number == 1
    
        def test_fikid(self):
            assert self.driver.fikid == -85641
    
        def test_pixel2focal_x(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([0, 0, -0.009])) as gdpool:
                 assert self.driver.pixel2focal_x == [0, 0, -0.009]
                 gdpool.assert_called_with('INS-85641_TRANSX', 0, 3)
    
        def test_pixel2focal_y(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([0, 0.009, 0])) as gdpool:
                 assert self.driver.pixel2focal_y == [0, 0.009, 0]
                 gdpool.assert_called_with('INS-85641_TRANSY', 0, 3)
    
        def test_detector_start_line(self):
            with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([244])) as gdpool:
                 assert self.driver.detector_start_line == 244
                 gdpool.assert_called_with('INS-85641_FILTER_OFFSET', 0, 3)
    
    # ========= Test WAC isislabel and isis spice driver =========
    class test_wac_isis_isis(unittest.TestCase):
    
        def setUp(self):
            label = get_image_label('wac0000a1c4.uv.even', 'isis3')
            self.driver = LroLrocWacIsisLabelIsisSpiceDriver(label)
    
        def test_short_mission_name(self):
            assert self.driver.short_mission_name == 'lro'
    
        def test_intrument_id(self):
            assert self.driver.instrument_id == 'LRO_LROCWAC_UV'
    
        def test_exposure_duration(self):
            np.testing.assert_almost_equal(self.driver.exposure_duration, 0.04)
    
        def test_usgscsm_distortion_model(self):
            assert self.driver.usgscsm_distortion_model == {'radial': {'coefficients': [-0.0258246, -4.66139e-05, -0.000144651]}}
    
        def test_filter_number(self):
            assert self.driver.filter_number == 1
    
        def test_fikid(self):
            assert self.driver.fikid == -85641
    
        def test_odtk(self):
            assert self.driver.odtk == [-0.0258246, -4.66139e-05, -0.000144651]