diff --git a/ale/base/label_isis.py b/ale/base/label_isis.py index d4612f4f5953d9edd8e758a9bea783a198bcb8cb..6d5ac20ac3eca0e17821b61d4940ca6ea07f142c 100644 --- a/ale/base/label_isis.py +++ b/ale/base/label_isis.py @@ -40,6 +40,17 @@ class IsisLabel(): """ return self.label['IsisCube']['Instrument']['SpacecraftName'] + @property + def spacecraft_name(self): + """ + Returns the name of the spacecraft + Returns + ------- + : str + Full name of the spacecraft + """ + return self.platform_name + @property def sensor_name(self): """ @@ -89,14 +100,16 @@ class IsisLabel(): return self.label['IsisCube']['Core']['Dimensions']['Samples'] @property - def sample_summing(self): + def sampling_factor(self): """ - Returns the number of detector samples summed to produce each image sample + Returns the summing factor from the PDS3 label. For example a return value of 2 + indicates that 2 lines and 2 samples (4 pixels) were summed and divided by 4 + to produce the output pixel value. Returns ------- : int - Sample summing + Number of samples and lines combined from the original data to produce a single pixel in this image """ try: summing = self.label['IsisCube']['Instrument']['SummingMode'] @@ -104,6 +117,18 @@ class IsisLabel(): summing = 1 return summing + @property + def sample_summing(self): + """ + Returns the number of detector samples summed to produce each image sample + + Returns + ------- + : int + Sample summing + """ + return self.sampling_factor + @property def line_summing(self): """ @@ -114,11 +139,7 @@ class IsisLabel(): : int Line summing """ - try: - summing = self.label['IsisCube']['Instrument']['SummingMode'] - except: - summing = 1 - return summing + return self.sampling_factor @property def target_name(self): diff --git a/ale/drivers/mes_drivers.py b/ale/drivers/mes_drivers.py index f5db260c7d6a997a4afb0757bacc4ff95d5678ce..2998dc29ee8ec027e260d295da376aa5dca7b6e6 100644 --- a/ale/drivers/mes_drivers.py +++ b/ale/drivers/mes_drivers.py @@ -294,13 +294,12 @@ class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver : int Naif ID code used in calculating focal length """ - if isinstance(self, Framer): + if(self.instrument_id == 'MSGR_MDIS_WAC'): fn = self.label['IsisCube']['BandBin']['Number'] if fn == 'N/A': fn = 0 - else: - fn = 0 - return self.ikid - int(fn) + return self.ikid - int(fn) + return self.ikid @property def focal_length(self): @@ -367,7 +366,7 @@ class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver : float detector center sample """ - return float(spice.gdpool('INS{}_BORESIGHT'.format(self.ikid), 0, 3)[0]) - 0.5 + return float(spice.gdpool('INS{}_CCD_CENTER'.format(self.ikid), 0, 3)[0]) - 0.5 @property @@ -385,7 +384,7 @@ class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver : float detector center line """ - return float(spice.gdpool('INS{}_BORESIGHT'.format(self.ikid), 0, 3)[1]) - 0.5 + return float(spice.gdpool('INS{}_CCD_CENTER'.format(self.ikid), 0, 3)[1]) - 0.5 @property def sensor_model_version(self): @@ -396,3 +395,34 @@ class MessengerMdisIsisLabelNaifSpiceDriver(IsisLabel, NaifSpice, Framer, Driver ISIS sensor model version """ return 2 + + @property + def pixel_size(self): + """ + Overriden because the MESSENGER IK uses PIXEL_PITCH and the units + are already millimeters + + Returns + ------- + : float pixel size + """ + return spice.gdpool('INS{}_PIXEL_PITCH'.format(self.ikid), 0, 1) + + @property + def sampling_factor(self): + """ + Returns the summing factor from the PDS3 label. For example a return value of 2 + indicates that 2 lines and 2 samples (4 pixels) were summed and divided by 4 + to produce the output pixel value. + + NOTE: This is overwritten for the messenger driver as the value is stored in "MESS:PIXELBIN" + + Returns + ------- + : int + Number of samples and lines combined from the original data to produce a single pixel in this image + """ + pixel_bin = self.label['IsisCube']['Instrument']['PixelBinningMode'] + if pixel_bin == 0: + pixel_bin = 1 + return pixel_bin * 2 diff --git a/tests/pytests/test_mdis_drivers.py b/tests/pytests/test_mdis_drivers.py index f147bd1cb5fb599c20b8bb16f816c6fedafc5424..2453540aa3e758ed0e7db4acb05719b2aa951fb5 100644 --- a/tests/pytests/test_mdis_drivers.py +++ b/tests/pytests/test_mdis_drivers.py @@ -9,6 +9,7 @@ import spiceypy as spice from conftest import get_image_kernels, convert_kernels from ale.drivers.mes_drivers import MessengerMdisPds3NaifSpiceDriver +from ale.drivers.mes_drivers import MessengerMdisIsisLabelNaifSpiceDriver @pytest.fixture(scope="module", autouse=True) def test_kernels(): @@ -20,9 +21,110 @@ def test_kernels(): for kern in binary_kernels: os.remove(kern) -@pytest.fixture -def Pds3Driver(): - pds_label = """ +@pytest.fixture(scope="module", params=["Pds3NaifDriver", "IsisNaifDriver"]) +def driver(request): + if request.param == "IsisNaifDriver": + label = """ +Object = IsisCube +Object = Core +StartByte = 65537 +Format = Tile +TileSamples = 512 +TileLines = 512 + +Group = Dimensions + Samples = 512 + Lines = 512 + Bands = 1 +End_Group + +Group = Pixels + Type = Real + ByteOrder = Lsb + Base = 0.0 + Multiplier = 1.0 +End_Group +End_Object + +Group = Instrument +SpacecraftName = Messenger +InstrumentName = "MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA" +InstrumentId = MDIS-NAC +TargetName = Mercury +OriginalTargetName = MERCURY +StartTime = 2015-04-24T04:42:19.666463 +StopTime = 2015-04-24T04:42:19.667463 +SpacecraftClockCount = 2/0072174528:989000 +MissionPhaseName = "MERCURY ORBIT YEAR 5" +ExposureDuration = 1 <MS> +ExposureType = AUTO +DetectorTemperature = -11.62 <DEGC> +FocalPlaneTemperature = 4.07 <DEGC> +FilterTemperature = N/A +OpticsTemperature = 17.08 <DEGC> +AttitudeQuality = Ok +FilterWheelPosition = 17348 +PivotPosition = 15 +FpuBinningMode = 1 +PixelBinningMode = 0 +SubFrameMode = 0 +JailBars = 0 +DpuId = DPU-A +PivotAngle = 0.04119873046875 <Degrees> +Unlutted = 1 +LutInversionTable = $messenger/calibration/LUT_INVERT/MDISLUTINV_0.TAB +End_Group + +Group = Archive +DataSetId = MESS-E/V/H-MDIS-2-EDR-RAWDATA-V1.0 +DataQualityId = 0000001000000000 +ProducerId = "APPLIED COHERENT TECHNOLOGY CORPORATION" +EdrSourceProductId = 1072174528_IM6 +ProductId = EN1072174528M +SequenceName = N/A +ObservationId = 8386282 +ObservationType = (Monochrome, "Ridealong NAC") +SiteId = N/A +MissionElapsedTime = 72174528 +EdrProductCreationTime = 2015-04-30T18:25:23 +ObservationStartTime = 2015-04-24T04:42:19.666463 +SpacecraftClockStartCount = 2/0072174528:989000 +SpacecraftClockStopCount = 2/0072174528:990000 +Exposure = 1 +CCDTemperature = 1139 +OriginalFilterNumber = 0 +OrbitNumber = 4086 +YearDoy = 2015114 +SourceProductId = ("EN1072174528M", "MDISLUTINV_0") +End_Group + +Group = BandBin +Name = "748 BP 53" +Number = 2 +Center = 747.7 <NM> +Width = 52.6 <NM> +End_Group + +Group = Kernels +NaifIkCode = -236820 +End_Group +End_Object + +Object = Label +Bytes = 65536 +End_Object + +Object = OriginalLabel +Name = IsisCube +StartByte = 1114113 +Bytes = 7944 +End_Object +End +""" + return MessengerMdisIsisLabelNaifSpiceDriver(label) + + else: + label = """ PDS_VERSION_ID = PDS3 /* ** FILE FORMAT ** */ @@ -245,23 +347,19 @@ Group = SUBFRAME5_PARAMETERS End_Group End """ - return MessengerMdisPds3NaifSpiceDriver(pds_label) - -def test_short_mission_name(Pds3Driver): - assert Pds3Driver.short_mission_name=='mes' + return MessengerMdisPds3NaifSpiceDriver(label) -@pytest.fixture -def IsisLabelDriver(): - return MessengerMdisIsisLabelNaifSpiceDriver("") +def test_short_mission_name(driver): + assert driver.short_mission_name == 'mes' -def test_test_image_lines(Pds3Driver): - assert Pds3Driver.image_lines == 512 +def test_test_image_lines(driver): + assert driver.image_lines == 512 -def test_image_samples(Pds3Driver): - assert Pds3Driver.image_lines == 512 +def test_image_samples(driver): + assert driver.image_samples == 512 -def test_usgscsm_distortion_model(Pds3Driver): - dist = Pds3Driver.usgscsm_distortion_model +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'] @@ -288,44 +386,44 @@ def test_usgscsm_distortion_model(Pds3Driver): 0.0, 1.0040104714688569E-5]) -def test_detector_start_line(Pds3Driver): - assert Pds3Driver.detector_start_line == 1 +def test_detector_start_line(driver): + assert driver.detector_start_line == 1 -def test_detector_start_sample(Pds3Driver): - assert Pds3Driver.detector_start_sample == 9 +def test_detector_start_sample(driver): + assert driver.detector_start_sample == 9 -def test_sample_summing(Pds3Driver): - assert Pds3Driver.sample_summing == 2 +def test_sample_summing(driver): + assert driver.sample_summing == 2 -def test_line_summing(Pds3Driver): - assert Pds3Driver.line_summing == 2 +def test_line_summing(driver): + assert driver.line_summing == 2 -def test_platform_name(Pds3Driver): - assert Pds3Driver.platform_name == 'MESSENGER' +def test_platform_name(driver): + assert driver.platform_name.upper() == 'MESSENGER' -def test_sensor_name(Pds3Driver): - assert Pds3Driver.sensor_name == 'MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA' +def test_sensor_name(driver): + assert driver.sensor_name == 'MERCURY DUAL IMAGING SYSTEM NARROW ANGLE CAMERA' -def test_target_body_radii(Pds3Driver): - np.testing.assert_equal(Pds3Driver.target_body_radii, [2439.4, 2439.4, 2439.4]) +def test_target_body_radii(driver): + np.testing.assert_equal(driver.target_body_radii, [2439.4, 2439.4, 2439.4]) -def test_focal_length(Pds3Driver): - assert Pds3Driver.focal_length == 549.5535053027719 +def test_focal_length(driver): + assert driver.focal_length == 549.5535053027719 -def test_detector_center_line(Pds3Driver): - assert Pds3Driver.detector_center_line == 512 +def test_detector_center_line(driver): + assert driver.detector_center_line == 512 -def test_detector_center_sample(Pds3Driver): - assert Pds3Driver.detector_center_sample == 512 +def test_detector_center_sample(driver): + assert driver.detector_center_sample == 512 -def test_sensor_position(Pds3Driver): +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 = Pds3Driver.sensor_position + 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]) @@ -339,26 +437,24 @@ def test_sensor_position(Pds3Driver): np.testing.assert_almost_equal(time, [image_et]) -def test_frame_chain(Pds3Driver): - assert Pds3Driver.frame_chain.has_node(1) - assert Pds3Driver.frame_chain.has_node(10011) - assert Pds3Driver.frame_chain.has_node(-236820) +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 = Pds3Driver.frame_chain.compute_rotation(10011, 1) + 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 = Pds3Driver.frame_chain.compute_rotation(-236820, 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(Pds3Driver): - position, velocity, time = Pds3Driver.sun_position +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]) @@ -372,18 +468,18 @@ def test_sun_position(Pds3Driver): np.testing.assert_almost_equal(time, [image_et]) -def test_target_name(Pds3Driver): - assert Pds3Driver.target_name == 'MERCURY' +def test_target_name(driver): + assert driver.target_name.upper() == 'MERCURY' -def test_target_frame_id(Pds3Driver): - assert Pds3Driver.target_frame_id == 10011 +def test_target_frame_id(driver): + assert driver.target_frame_id == 10011 -def test_sensor_frame_id(Pds3Driver): - assert Pds3Driver.sensor_frame_id == -236820 +def test_sensor_frame_id(driver): + assert driver.sensor_frame_id == -236820 -def test_isis_naif_keywords(Pds3Driver): +def test_isis_naif_keywords(driver): expected_keywords = { - 'BODY199_RADII' : Pds3Driver.target_body_radii, + 'BODY199_RADII' : driver.target_body_radii, 'BODY_FRAME_CODE' : 10011, 'INS-236820_PIXEL_SIZE' : 0.014, 'INS-236820_ITRANSL' : [0.0, 0.0, 71.42857143], @@ -392,37 +488,37 @@ def test_isis_naif_keywords(Pds3Driver): 'INS-236820_BORESIGHT_SAMPLE' : 512.5, 'INS-236820_BORESIGHT_LINE' : 512.5 } - assert set(Pds3Driver.isis_naif_keywords.keys()) == set(expected_keywords.keys()) - for key, value in Pds3Driver.isis_naif_keywords.items(): + assert set(driver.isis_naif_keywords.keys()) == set(expected_keywords.keys()) + for key, value in driver.isis_naif_keywords.items(): if isinstance(value, np.ndarray): np.testing.assert_almost_equal(value, expected_keywords[key]) else: assert value == expected_keywords[key] -def test_sensor_model_version(Pds3Driver): - assert Pds3Driver.sensor_model_version == 2 +def test_sensor_model_version(driver): + assert driver.sensor_model_version == 2 -def test_focal2pixel_lines(Pds3Driver): - np.testing.assert_almost_equal(Pds3Driver.focal2pixel_lines, +def test_focal2pixel_lines(driver): + np.testing.assert_almost_equal(driver.focal2pixel_lines, [0.0, 0.0, 71.42857143]) -def test_focal2pixel_samples(Pds3Driver): - np.testing.assert_almost_equal(Pds3Driver.focal2pixel_samples, +def test_focal2pixel_samples(driver): + np.testing.assert_almost_equal(driver.focal2pixel_samples, [0.0, 71.42857143, 0.0]) -def test_pixel2focal_x(Pds3Driver): - np.testing.assert_almost_equal(Pds3Driver.pixel2focal_x, +def test_pixel2focal_x(driver): + np.testing.assert_almost_equal(driver.pixel2focal_x, [0.0, 0.014, 0.0]) -def test_pixel2focal_y(Pds3Driver): - np.testing.assert_almost_equal(Pds3Driver.pixel2focal_y, +def test_pixel2focal_y(driver): + np.testing.assert_almost_equal(driver.pixel2focal_y, [0.0, 0.0, 0.014]) -def test_ephemeris_start_time(Pds3Driver): - assert Pds3Driver.ephemeris_start_time == 483122606.8520247 +def test_ephemeris_start_time(driver): + assert driver.ephemeris_start_time == 483122606.8520247 -def test_ephemeris_stop_time(Pds3Driver): - assert Pds3Driver.ephemeris_stop_time == 483122606.85302466 +def test_ephemeris_stop_time(driver): + assert driver.ephemeris_stop_time == 483122606.85302466 -def test_center_ephemeris_time(Pds3Driver): - assert Pds3Driver.center_ephemeris_time == 483122606.85252464 +def test_center_ephemeris_time(driver): + assert driver.center_ephemeris_time == 483122606.85252464