Skip to content
Snippets Groups Projects
Select Git revision
  • 2b492b9217710813fe90fa25733f9aa549f6e8be
  • master default protected
  • feature/kasm_0.9.2
3 results

user-dirs.locale

Blame
  • test_kaguya_drivers.py 15.08 KiB
    import pytest
    import os
    import numpy as np
    import datetime
    import spiceypy as spice
    from importlib import reload
    import json
    
    import unittest
    from unittest.mock import MagicMock, PropertyMock, patch
    
    from conftest import get_image_label, get_image_kernels, convert_kernels, compare_dicts
    
    import ale
    
    from ale.drivers.selene_drivers import KaguyaTcPds3NaifSpiceDriver
    
    image_dict = {
        # Kaguya TC1
        'TC1S2B0_01_06691S820E0465' : {
            'usgscsm': {
                'radii': {
                    'semimajor': 1737.4,
                    'semiminor': 1737.4,
                    'unit': 'km'},
                'sensor_position': {
                    'positions': np.array([[195490.61933009, 211972.79163854, -1766965.21759375],
                                           [194934.34274256, 211332.14192709, -1767099.36601459],
                                           [194378.02078141, 210691.44358962, -1767233.10640484],
                                           [193821.65246371, 210050.69819792, -1767366.43865632],
                                           [193265.23762617, 209409.90567475, -1767499.36279925],
                                           [192708.77531467, 208769.0676026, -1767631.87872367]]),
                    'velocities': np.array([[-1069.71186948, -1231.97377674, -258.3672068 ],
                                            [-1069.80166655, -1232.06495814, -257.58238805],
                                            [-1069.89121909, -1232.15585752, -256.7975062 ],
                                            [-1069.98052705, -1232.24647484, -256.01256158],
                                            [-1070.06959044, -1232.3368101, -255.2275542 ],
                                            [-1070.15840923, -1232.42686325, -254.44248439]]),
                     'unit': 'm'},
                 'sun_position': {
                    'positions': np.array([[9.50465237e+10, 1.15903815e+11, 3.78729685e+09]]),
                    'velocities': np.array([[285707.13474515, -232731.15884149, 592.91742112]]),
                    'unit': 'm'},
                 'sensor_orientation': {
                    'quaternions': np.array([[-0.19095485, -0.08452708,  0.88748467, -0.41080698],
                                             [-0.19073945, -0.08442789,  0.88753312, -0.41082276],
                                             [-0.19052404, -0.08432871,  0.88758153, -0.41083852],
                                             [-0.19030862, -0.08422952,  0.88762988, -0.41085426],
                                             [-0.19009352, -0.08412972,  0.88767854, -0.41086914],
                                             [-0.18987892, -0.08402899,  0.88772773, -0.41088271]])},
                'detector_sample_summing': 1,
                'detector_line_summing': 1,
                'focal_length_model': {
                    'focal_length': 72.45},
                'detector_center': {
                    'line': 0.5,
                    'sample': 2048.0},
                'starting_detector_line': 1,
                'starting_detector_sample': .5,
                'focal2pixel_lines': [0, 142.85714285714286, 0],
                'focal2pixel_samples': [0, 0, -142.85714285714286],
                'optical_distortion': {
                    'kaguyalism': {
                        'x': [-0.0009649900000000001, 0.00098441, 8.5773e-06, -3.7438e-06],
                        'y': [-0.0013796, 1.3502e-05, 2.7251e-06, -6.193800000000001e-06],
                        'boresight_x' : -0.0725,
                        'boresight_y' : 0.0214}},
                'image_lines': 400,
                'image_samples': 3208,
                'name_platform': 'SELENE-M',
                'name_sensor': 'Terrain Camera 1',
                'reference_height': {
                    'maxheight': 1000,
                    'minheight': -1000,
                    'unit': 'm'},
                'name_model': 'USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL',
                'interpolation_method': 'lagrange',
                'line_scan_rate': [[0.5, -1.300000011920929, 0.006500000000000001]],
                'starting_ephemeris_time': 292234259.82293594,
                'center_ephemeris_time': 292234261.12293595,
                't0_ephemeris': -1.300000011920929,
                'dt_ephemeris': 0.5200000047683716,
                't0_quaternion': -1.300000011920929,
                'dt_quaternion': 0.5200000047683716
            }
        },
        'MVA_2B2_01_02329N002E0302' : {
            'usgscsm': {
                "radii": {
                    "semimajor": 1737.4,
                    "semiminor": 1737.4,
                    "unit": "km"
                },
                "sensor_position": {
                    "positions":
                        [[1581631.170967984, 918816.7454749601, 17359.778053074166],
                         [1581653.6518666577, 918814.107469728, 15896.70384782562],
                         [1581675.125610955, 918810.8848940814, 14433.619458749732],
                         [1581695.5934041755, 918807.0763904197, 12970.525577080793],
                         [1581715.0540239091, 918802.6833137124, 11507.423371723235],
                         [1581733.5087290092, 918797.7043282809, 10044.31354866982],
                         [1581750.956214992, 918792.1408047304, 8581.197251839967],
                         [1581767.397120705, 918785.9920686551, 7118.075256110188],
                         [1581782.832060649, 918779.2574662118, 5654.948478420991],
                         [1581797.2597721093, 918771.9383358458, 4191.818019885403],
                         [1581810.6815028861, 918764.0333783475, 2728.6845793242946],
                         [1581823.0960200944, 918755.5439313636, 1265.5493310270317],
                         [1581834.5045334753, 918746.4686686409, -197.58704133484173],
                         [1581844.9058070402, 918736.8089392016, -1660.7233725491283],
                         [1581854.3010902032, 918726.5634377429, -3123.8589609802857]],
                    "velocities":
                        [[25.783286973637825, -2.6305942733908934, -1641.2662531260032],
                         [24.6541610233529, -3.2871454607723085, -1641.2783248089215],
                         [23.52502323352204, -3.943685198289895, -1641.289353750218],
                         [22.395874155219467, -4.600213174108102, -1641.2993399473512],
                         [21.26671464756069, -5.256728894126663, -1641.3082833954215],
                         [20.137545263644594, -5.913232045800747, -1641.3161840918588],
                         [19.008366863699095, -6.5697221353508475, -1641.3230420322975],
                         [17.87918004057494, -7.226198826543763, -1641.3288572140555],
                         [16.749985499845394, -7.88266171782453, -1641.3336296337216],
                         [15.620784065823575, -8.539110335934271, -1641.337359287963],
                         [14.491576292730104, -9.19554436926745, -1641.3400461741676],
                         [13.36236304437793, -9.85196332233081, -1641.3416902893532],
                         [12.23314487464595, -10.508366882000841, -1641.3422916309216],
                         [11.103922649257456, -11.164754553522712, -1641.341850196455],
                         [9.974696922853957, -11.821126023917325, -1641.3403659833964]],
                     "unit": "m"
                },
                "sun_position": {
                    "positions": [[108404801770.5306, 104307744789.75961, 3666393216.4922094]],
                    "velocities": [[257322.0926607856, -265899.8379709762, 700.5524232754503]],
                    "unit": "m"
                },
                "sensor_orientation": {
                    "quaternions":
                    [[0.6841290215141231, 0.18168313624920118, -0.6816280982629065, 0.18531555677620887],
                     [0.6838528388829476, 0.18161279386087273, -0.6819012144243979, 0.18539908744196368],
                     [0.6835758239500531, 0.18154309699572227, -0.6821746518347966, 0.18548299447195182],
                     [0.6832967471554302, 0.18147561929758188, -0.6824496703005432, 0.18556562837456525],
                     [0.6830162583395626, 0.18140960968119488, -0.6827257032744798, 0.18564740355713963],
                     [0.6827351210778349, 0.18134352304219054, -0.6830025370795092, 0.18572779932049618],
                     [0.6824529044894799, 0.1812773209250331, -0.6832809057747644, 0.18580573154704597],
                     [0.6821706589155502, 0.18121103113539608, -0.6835592153840321, 0.18588317130159213],
                     [0.681888970523384, 0.18114425688445818, -0.683837844473224, 0.1859569642217031],
                     [0.6816071682054932, 0.1810774530787411, -0.6841163595700203, 0.1860307254355251],
                     [0.681327502040239, 0.18100853678321963, -0.6843942771188167, 0.18610002155351393],
                     [0.6810480612976251, 0.1809392785030075, -0.6846720093765764, 0.18616862054008748],
                     [0.6807714840034947, 0.18086571980771243, -0.6849487531729829, 0.18623367980280572],
                     [0.6804965752593046, 0.18078957882144664, -0.6852248624334619, 0.1862966106856612],
                     [0.6802234034550377, 0.18071156643840802, -0.6854997575134238, 0.1863586155681002]]
                },
                "detector_sample_summing": 1,
                "detector_line_summing": 1,
                "focal_length_model": {
                    "focal_length": 65.4
                },
                "detector_center": {
                    "line": 0.5,
                    "sample": 483.5
                },
                "starting_detector_line": 0,
                "starting_detector_sample": 0,
                "focal2pixel_lines": [0, 76.92307692307692, 0],
                "focal2pixel_samples": [0, 0, -76.92307692307692],
                "optical_distortion": {
                    "kaguyalism": {
                        "x": [2.8912e-19, 0.00020899000000000002, 4.7727000000000006e-05],
                        "y": [-1.0119e-18, 0.0034982, 1.9597e-05],
                        "boresight_x": -0.0060,
                        "boresight_y": -0.0187
                    }
                },
                "image_lines": 960,
                "image_samples": 962,
                "name_platform": "SELENE MAIN ORBITER",
                "name_sensor": "MULTIBAND IMAGER VISIBLE",
                "reference_height": {
                    "maxheight": 1000,
                    "minheight": -1000,
                    "unit": "m"
                },
                "name_model": "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL",
                "interpolation_method": "lagrange",
                "line_scan_rate": [[0.5, -6.239987522363663, 0.012999974000000001]],
                "starting_ephemeris_time": 261664552.50899568,
                "center_ephemeris_time": 261664558.7489832,
                "t0_ephemeris": -6.239987522363663,
                "dt_ephemeris": 0.8914267889090947,
                "t0_quaternion": -6.239987522363663,
                "dt_quaternion": 0.8914267889090947
            }
        }
    }
    
    
    @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)
    
    @pytest.mark.parametrize("label_type", ['pds3'])
    @pytest.mark.parametrize("formatter", ['usgscsm'])
    @pytest.mark.parametrize("image", image_dict.keys())
    def test_kaguya_load(test_kernels, label_type, formatter, image):
        label_file = get_image_label(image, label_type)
    
        usgscsm_isd_str = ale.loads(label_file, props={'kernels': test_kernels[image]}, formatter=formatter)
        usgscsm_isd_obj = json.loads(usgscsm_isd_str)
        print(json.dumps(usgscsm_isd_obj, indent=2))
    
        assert compare_dicts(usgscsm_isd_obj, image_dict[image][formatter]) == []
    
    # ========= Test pdslabel and naifspice driver =========
    class test_pds_naif(unittest.TestCase):
    
        def setUp(self):
            label = get_image_label("TC1S2B0_01_06691S820E0465", "pds3")
            self.driver = KaguyaTcPds3NaifSpiceDriver(label)
    
        def test_short_mission_name(self):
            assert self.driver.short_mission_name == 'selene'
    
        def test_utc_start_time(self):
            assert self.driver.utc_start_time == datetime.datetime(2009, 4, 5, 20, 9, 53, 607478, tzinfo=datetime.timezone.utc)
    
        def test_utc_stop_time(self):
            assert self.driver.utc_stop_time == datetime.datetime(2009, 4, 5, 20, 10, 23, 864978, tzinfo=datetime.timezone.utc)
    
        def test_instrument_id(self):
            assert self.driver.instrument_id == 'LISM_TC1_STF'
    
        def test_sensor_frame_id(self):
            with patch('ale.drivers.selene_drivers.spice.namfrm', return_value=12345) as namfrm:
                assert self.driver.sensor_frame_id == 12345
                namfrm.assert_called_with('LISM_TC1_HEAD')
    
        def test_instrument_host_name(self):
            assert self.driver.instrument_host_name == 'SELENE-M'
    
        def test_ikid(self):
            with patch('ale.drivers.selene_drivers.spice.bods2c', return_value=12345) as bods2c:
                assert self.driver.ikid == 12345
                bods2c.assert_called_with('LISM_TC1')
    
        def test_spacecraft_name(self):
            assert self.driver.spacecraft_name == 'SELENE'
    
        def test_spacecraft_clock_start_count(self):
            assert self.driver.spacecraft_clock_start_count == 922997380.174174
    
        def test_spacecraft_clock_stop_count(self):
            assert self.driver.spacecraft_clock_stop_count == 922997410.431674
    
        def test_ephemeris_start_time(self):
            with patch('ale.drivers.selene_drivers.spice.sct2e', return_value=12345) as sct2e, \
                 patch('ale.drivers.selene_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.ephemeris_start_time == 12345
                sct2e.assert_called_with(-12345, 922997380.174174)
    
        def test_detector_center_line(self):
            with patch('ale.drivers.selene_drivers.spice.gdpool', return_value=np.array([54321, 12345])) as gdpool, \
                 patch('ale.drivers.selene_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.detector_center_line == 12344.5
                gdpool.assert_called_with('INS-12345_CENTER', 0, 2)
    
        def test_detector_center_sample(self):
            with patch('ale.drivers.selene_drivers.spice.gdpool', return_value=np.array([54321, 12345])) as gdpool, \
                 patch('ale.drivers.selene_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.detector_center_sample == 54320.5
                gdpool.assert_called_with('INS-12345_CENTER', 0, 2)
    
        def test_focal2pixel_samples(self):
            with patch('ale.drivers.selene_drivers.spice.gdpool', return_value=np.array([2])) as gdpool, \
                 patch('ale.drivers.selene_drivers.spice.bods2c', return_value=-12345) as bods2c:
                assert self.driver.focal2pixel_samples == [0, 0, -1/2]
                gdpool.assert_called_with('INS-12345_PIXEL_SIZE', 0, 1)
    
        def test_focal2pixel_lines(self):
            with patch('ale.drivers.selene_drivers.spice.gdpool', return_value=np.array([2])) as gdpool, \
                 patch('ale.drivers.selene_drivers.spice.bods2c', return_value=-12345) as bods2c, \
                 patch('ale.drivers.selene_drivers.KaguyaTcPds3NaifSpiceDriver.spacecraft_direction', \
                 new_callable=PropertyMock) as spacecraft_direction:
                spacecraft_direction.return_value = 1
                assert self.driver.focal2pixel_lines == [0, 1/2, 0]
                spacecraft_direction.return_value = -1
                assert self.driver.focal2pixel_lines == [0, -1/2, 0]
                gdpool.assert_called_with('INS-12345_PIXEL_SIZE', 0, 1)
    
        def test_spacecraft_direction(self):
            assert self.driver.spacecraft_direction == 1