Skip to content
Snippets Groups Projects
Commit 89cf4c57 authored by Jesse Mapel's avatar Jesse Mapel Committed by Stuart Sides
Browse files

Updated MDIS tests to new load approach (#261)

* Updated MDIS tests to new load approach

* Added scope back to test_kernels fixture in mdis

* Fixed warning and minor updates

* Updated MDIS tests again

* Clean up from comments
parent c821b1da
No related branches found
No related tags found
No related merge requests found
......@@ -331,8 +331,8 @@ class NaifSpice():
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 = [p * -1000 for p in pos]
self._velocity = [v * -1000 for v in vel]
self._position = np.asarray([p * -1000 for p in pos])
self._velocity = np.asarray([v * -1000 for v in vel])
return self._position, self._velocity, self.ephemeris_time
@property
......
......@@ -51,7 +51,7 @@ class LineScanner():
: ndarray
ephemeris times split based on image lines
"""
return np.linspace(self.ephemeris_start_time, self.ephemeris_stop_time, self.image_lines / 64)
return np.linspace(self.ephemeris_start_time, self.ephemeris_stop_time, max(2, int(self.image_lines / 64)))
@property
def ephemeris_stop_time(self):
......
......@@ -223,8 +223,24 @@ class MessengerMdisPds3NaifSpiceDriver(Framer, Pds3Label, NaifSpice, Driver):
class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver):
"""
Driver for reading MDIS ISIS3 Labels. These are Labels that have been ingested
into ISIS from PDS EDR images but have not been spiceinit'd yet.
into ISIS from PDS EDR images. Any SPCIE data attached by the spiceinit application
will be ignored.
"""
@property
def platform_name(self):
"""
Returns the name of the platform containing the sensor. This is usually
the spacecraft name.
Messenger MDIS ISIS labels use upper camel case so this converts it to
all upper case.
Returns
-------
: str
Spacecraft name
"""
return super().platform_name.upper()
@property
def instrument_id(self):
......@@ -315,7 +331,7 @@ class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver
: double
focal length in meters
"""
coeffs = spice.gdpool('INS{}_FL_TEMP_COEFFS '.format(self.fikid), 0, 5)
coeffs = spice.gdpool('INS{}_FL_TEMP_COEFFS'.format(self.fikid), 0, 6)
# reverse coeffs, MDIS coeffs are listed a_0, a_1, a_2 ... a_n where
# numpy wants them a_n, a_n-1, a_n-2 ... a_0
f_t = np.poly1d(coeffs[::-1])
......
......@@ -65,7 +65,6 @@ def test_kernels():
def test_dawn_load(test_kernels, usgscsm_compare_dict):
label_file = get_image_label('FC21A0038582_15170161546F6F')
usgscsm_isd = ale.load(label_file, props={'kernels': test_kernels}, formatter='usgscsm')
print(usgscsm_isd)
assert compare_dicts(usgscsm_isd, usgscsm_compare_dict) == []
......
......@@ -4,230 +4,206 @@ import numpy as np
import spiceypy as spice
from importlib import reload
import json
import unittest
from unittest.mock import patch
from conftest import get_image_label, get_image_kernels, convert_kernels
from conftest import get_image_label, get_image_kernels, convert_kernels, compare_dicts
import ale
from ale.drivers.mes_drivers import MessengerMdisPds3NaifSpiceDriver
from ale.drivers.mes_drivers import MessengerMdisIsisLabelNaifSpiceDriver
@pytest.fixture(scope="module", autouse=True)
@pytest.fixture(scope='module')
def test_kernels():
kernels = get_image_kernels('EN1072174528M')
updated_kernels, binary_kernels = convert_kernels(kernels)
spice.furnsh(updated_kernels)
yield updated_kernels
spice.unload(updated_kernels)
for kern in binary_kernels:
os.remove(kern)
@pytest.fixture(params=["Pds3NaifDriver", "IsisNaifDriver"])
def driver(request):
if request.param == "IsisNaifDriver":
label = get_image_label("EN1072174528M", "isis3")
return MessengerMdisIsisLabelNaifSpiceDriver(label)
@pytest.fixture()
def usgscsm_compare_dict():
return {
'radii': {
'semimajor': 2439.4,
'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]]),
'unit': 'm'},
'sun_position': {
'positions': np.array([[-4.68946673e+10, -5.36158427e+08, 2.71167863e+07]]),
'velocities': np.array([[-4629.73346128, 256.72086237, 10.63960444]]),
'unit': 'm'},
'sensor_orientation': {
'quaternions': np.array([[ 0.93418372, 0.00144773, -0.00449382, -0.35676112]])},
'detector_sample_summing': 2,
'detector_line_summing': 2,
'focal_length_model': {
'focal_length': 549.5535053027719},
'detector_center': {
'line': 512,
'sample': 512},
'starting_detector_line': 1,
'starting_detector_sample': 9,
'focal2pixel_lines': [0.0, 0.0, 71.42857143],
'focal2pixel_samples': [0.0, 71.42857143, 0.0],
'optical_distortion': {
'transverse': {
'x': [0.0, 1.001854269623802, 0.0, 0.0, -0.0005094440474941111, 0.0, 1.004010471468856e-05, 0.0, 1.004010471468856e-05, 0.0],
'y': [0.0, 0.0, 1.0, 0.0009060010594996751, 0.0, 0.0003574842626620758, 0.0, 1.004010471468856e-05, 0.0, 1.004010471468856e-05]}},
'image_lines': 512,
'image_samples': 512,
'name_platform': 'MESSENGER',
'name_sensor': 'MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA',
'reference_height': {
'maxheight': 1000,
'minheight': -1000,
'unit': 'm'},
'name_model': 'USGS_ASTRO_FRAME_SENSOR_MODEL',
'center_ephemeris_time': 483122606.85252464}
@pytest.mark.parametrize("label_type", ["pds3", "isis3"])
def test_load(test_kernels, usgscsm_compare_dict, label_type):
label_file = get_image_label('EN1072174528M', label_type)
usgscsm_isd_str = ale.loads(label_file, props={'kernels': test_kernels}, formatter='usgscsm')
usgscsm_isd_obj = json.loads(usgscsm_isd_str)
else:
assert compare_dicts(usgscsm_isd_obj, usgscsm_compare_dict) == []
# ========= Test Pds3 Label and NAIF Spice driver =========
class test_pds3_naif(unittest.TestCase):
def setUp(self):
label = get_image_label("EN1072174528M", "pds3")
return MessengerMdisPds3NaifSpiceDriver(label)
self.driver = MessengerMdisPds3NaifSpiceDriver(label)
def test_short_mission_name(driver):
assert driver.short_mission_name=='mes'
def test_short_mission_name(self):
assert self.driver.short_mission_name=='mes'
def test_no_metakernels(driver, tmpdir, monkeypatch):
monkeypatch.setenv('ALESPICEROOT', str(tmpdir))
reload(ale)
def test_spacecraft_name(self):
assert self.driver.spacecraft_name == 'MESSENGER'
with pytest.raises(ValueError):
with driver as failure:
pass
def test_fikid(self):
with patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.spacecraft_name == 'MESSENGER'
def test_no_spice_root(driver, monkeypatch):
monkeypatch.delenv('ALESPICEROOT', raising=False)
reload(ale)
def test_instrument_id(self):
assert self.driver.instrument_id == 'MSGR_MDIS_NAC'
with pytest.raises(EnvironmentError):
with driver as failure:
pass
def test_sampling_factor(self):
assert self.driver.sampling_factor == 2
def test_load(test_kernels):
label_file = get_image_label('EN1072174528M')
def test_focal_length(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([pow(4.07, -x) for x in np.arange(6)])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.focal_length == pytest.approx(6.0)
gdpool.assert_called_with('INS-12345_FL_TEMP_COEFFS', 0, 6)
usgscsm_isd_str = ale.loads(label_file, props={'kernels': test_kernels}, formatter='usgscsm')
usgscsm_isd_obj = json.loads(usgscsm_isd_str)
def test_detector_start_sample(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([10.0])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_start_sample == 10.0
gdpool.assert_called_with('INS-12345_FPUBIN_START_SAMPLE', 0, 1)
def test_detector_start_line(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([10.0])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_start_line == 10.0
gdpool.assert_called_with('INS-12345_FPUBIN_START_LINE', 0, 1)
assert usgscsm_isd_obj['name_platform'] == 'MESSENGER'
assert usgscsm_isd_obj['name_sensor'] == 'MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA'
assert usgscsm_isd_obj['name_model'] == 'USGS_ASTRO_FRAME_SENSOR_MODEL'
def test_test_image_lines(driver):
assert driver.image_lines == 512
def test_image_samples(driver):
assert driver.image_samples == 512
def test_usgscsm_distortion_model(driver):
dist = driver.usgscsm_distortion_model
assert 'transverse' in dist
assert 'x' in dist['transverse']
assert 'y' in dist['transverse']
np.testing.assert_almost_equal(dist['transverse']['x'],
[0.0,
1.0018542696238023333,
0.0,
0.0,
-5.0944404749411114E-4,
0.0,
1.0040104714688569E-5,
0.0,
1.0040104714688569E-5,
0.0])
np.testing.assert_almost_equal(dist['transverse']['y'],
[0.0,
0.0,
1.0,
9.06001059499675E-4,
0.0,
3.5748426266207586E-4,
0.0,
1.0040104714688569E-5,
0.0,
1.0040104714688569E-5])
def test_detector_start_line(driver):
assert driver.detector_start_line == 1
def test_detector_start_sample(driver):
assert driver.detector_start_sample == 9
def test_sample_summing(driver):
assert driver.sample_summing == 2
def test_line_summing(driver):
assert driver.line_summing == 2
def test_platform_name(driver):
assert driver.platform_name.upper() == 'MESSENGER'
def test_sensor_name(driver):
assert driver.sensor_name == 'MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA'
def test_target_body_radii(driver):
np.testing.assert_equal(driver.target_body_radii, [2439.4, 2439.4, 2439.4])
def test_focal_length(driver):
assert driver.focal_length == 549.5535053027719
def test_detector_center_line(driver):
assert driver.detector_center_line == 512
def test_detector_center_sample(driver):
assert driver.detector_center_sample == 512
def test_sensor_position(driver):
"""
Returns
-------
: (positions, velocities, times)
a tuple containing a list of positions, a list of velocities, and a list of times
"""
position, velocity, time = driver.sensor_position
image_et = spice.scs2e(-236, '2/0072174528:989000') + 0.0005
expected_state, _ = spice.spkez(199, image_et, 'IAU_MERCURY', 'LT+S', -236)
expected_position = -1000 * np.asarray(expected_state[:3])
expected_velocity = -1000 * np.asarray(expected_state[3:])
np.testing.assert_allclose(position,
[expected_position],
rtol=1e-8)
np.testing.assert_allclose(velocity,
[expected_velocity],
rtol=1e-8)
np.testing.assert_almost_equal(time,
[image_et])
def test_frame_chain(driver):
assert driver.frame_chain.has_node(1)
assert driver.frame_chain.has_node(10011)
assert driver.frame_chain.has_node(-236820)
image_et = spice.scs2e(-236, '2/0072174528:989000') + 0.0005
target_to_j2000 = driver.frame_chain.compute_rotation(10011, 1)
target_to_j2000_mat = spice.pxform('IAU_MERCURY', 'J2000', image_et)
target_to_j2000_quats = spice.m2q(target_to_j2000_mat)
np.testing.assert_almost_equal(target_to_j2000.quats,
[-np.roll(target_to_j2000_quats, -1)])
sensor_to_j2000 = driver.frame_chain.compute_rotation(-236820, 1)
sensor_to_j2000_mat = spice.pxform('MSGR_MDIS_NAC', 'J2000', image_et)
sensor_to_j2000_quats = spice.m2q(sensor_to_j2000_mat)
np.testing.assert_almost_equal(sensor_to_j2000.quats,
[-np.roll(sensor_to_j2000_quats, -1)])
def test_sun_position(driver):
position, velocity, time = driver.sun_position
image_et = spice.scs2e(-236, '2/0072174528:989000') + 0.0005
expected_state, _ = spice.spkez(10, image_et, 'IAU_MERCURY', 'LT+S', 199)
expected_position = 1000 * np.asarray(expected_state[:3])
expected_velocity = 1000 * np.asarray(expected_state[3:])
np.testing.assert_allclose(position,
[expected_position],
rtol=1e-8)
np.testing.assert_allclose(velocity,
[expected_velocity],
rtol=1e-8)
np.testing.assert_almost_equal(time,
[image_et])
def test_target_name(driver):
assert driver.target_name.upper() == 'MERCURY'
def test_target_frame_id(driver):
assert driver.target_frame_id == 10011
def test_sensor_frame_id(driver):
assert driver.sensor_frame_id == -236820
def test_isis_naif_keywords(driver):
expected_keywords = {
'BODY199_RADII' : driver.target_body_radii,
'BODY_FRAME_CODE' : 10011,
'INS-236820_PIXEL_PITCH' : 0.014,
'INS-236820_ITRANSL' : [0.0, 0.0, 71.42857143],
'INS-236820_ITRANSS' : [0.0, 71.42857143, 0.0],
'INS-236820_FOCAL_LENGTH' : 549.1178195372703,
'INS-236820_BORESIGHT_SAMPLE' : 512.5,
'INS-236820_BORESIGHT_LINE' : 512.5
}
print(driver.isis_naif_keywords.keys())
assert set(expected_keywords.keys()).issubset(set(driver.isis_naif_keywords.keys()))
for key, value in expected_keywords.items():
if isinstance(value, np.ndarray) or isinstance(value, list):
np.testing.assert_almost_equal(value, driver.isis_naif_keywords[key])
else:
assert value == driver.isis_naif_keywords[key]
def test_sensor_model_version(driver):
assert driver.sensor_model_version == 2
def test_focal2pixel_lines(driver):
np.testing.assert_almost_equal(driver.focal2pixel_lines,
[0.0, 0.0, 71.42857143])
def test_focal2pixel_samples(driver):
np.testing.assert_almost_equal(driver.focal2pixel_samples,
[0.0, 71.42857143, 0.0])
def test_pixel2focal_x(driver):
np.testing.assert_almost_equal(driver.pixel2focal_x,
[0.0, 0.014, 0.0])
def test_pixel2focal_y(driver):
np.testing.assert_almost_equal(driver.pixel2focal_y,
[0.0, 0.0, 0.014])
def test_ephemeris_start_time(driver):
assert driver.ephemeris_start_time == 483122606.8520247
def test_ephemeris_stop_time(driver):
assert driver.ephemeris_stop_time == 483122606.85302466
def test_center_ephemeris_time(driver):
assert driver.center_ephemeris_time == 483122606.85252464
def test_detector_center_sample(self):
assert self.driver.detector_center_sample == 512
def test_detector_center_line(self):
assert self.driver.detector_center_line == 512
def test_sensor_model_version(self):
assert self.driver.sensor_model_version == 2
def test_usgscsm_distortion_model(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', side_effect=[np.array([1, 2, 3, 4, 5]), np.array([-1, -2, -3, -4, -5])]) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.usgscsm_distortion_model == {"transverse" : {
"x" : [1, 2, 3, 4, 5],
"y" : [-1, -2, -3, -4, -5]}}
def test_pixel_size(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([0.1])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.pixel_size == 0.1
gdpool.assert_called_with('INS-12345_PIXEL_PITCH', 0, 1)
# ========= Test ISIS3 Label and NAIF Spice driver =========
class test_isis3_naif(unittest.TestCase):
def setUp(self):
label = get_image_label("EN1072174528M", "isis3")
self.driver = MessengerMdisIsisLabelNaifSpiceDriver(label)
def test_short_mission_name(self):
assert self.driver.short_mission_name=='mes'
def test_platform_name(self):
assert self.driver.platform_name == 'MESSENGER'
def test_fikid(self):
with patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.spacecraft_name == 'MESSENGER'
def test_instrument_id(self):
assert self.driver.instrument_id == 'MSGR_MDIS_NAC'
def test_sampling_factor(self):
assert self.driver.sampling_factor == 2
def test_focal_length(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([pow(4.07, -x) for x in np.arange(6)])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.focal_length == pytest.approx(6.0)
gdpool.assert_called_with('INS-12345_FL_TEMP_COEFFS', 0, 6)
def test_detector_start_sample(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([10.0])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_start_sample == 10.0
gdpool.assert_called_with('INS-12345_FPUBIN_START_SAMPLE', 0, 1)
def test_detector_start_line(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([10.0])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_start_line == 10.0
gdpool.assert_called_with('INS-12345_FPUBIN_START_LINE', 0, 1)
def test_detector_center_sample(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([512.5, 512.5, 1])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_center_sample == 512
gdpool.assert_called_with('INS-12345_CCD_CENTER', 0, 3)
def test_detector_center_line(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([512.5, 512.5, 1])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.detector_center_line == 512
gdpool.assert_called_with('INS-12345_CCD_CENTER', 0, 3)
def test_sensor_model_version(self):
assert self.driver.sensor_model_version == 2
def test_usgscsm_distortion_model(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', side_effect=[np.array([1, 2, 3, 4, 5]), np.array([-1, -2, -3, -4, -5])]) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.usgscsm_distortion_model == {"transverse" : {
"x" : [1, 2, 3, 4, 5],
"y" : [-1, -2, -3, -4, -5]}}
def test_pixel_size(self):
with patch('ale.drivers.mes_drivers.spice.gdpool', return_value=np.array([0.1])) as gdpool, \
patch('ale.base.data_naif.spice.bods2c', return_value=-12345) as bods2c:
assert self.driver.pixel_size == 0.1
gdpool.assert_called_with('INS-12345_PIXEL_PITCH', 0, 1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment