From 0ba7b24e2f71317a98eb24ceb49b989360ec08c3 Mon Sep 17 00:00:00 2001 From: Austin Sanders <arsanders@usgs.gov> Date: Thu, 13 Jun 2024 13:01:21 -0600 Subject: [PATCH] M3 PDS3 NaifSpice Driver (#608) * Chandrayaan m3 PDS3 NaifSpice Driver and tests * Chandrayaan 1 M3 PDS test data * Removed incorrect docstring return information * renamed LBL to lbl for case-sensitive OS * Updated docstrings --- ale/drivers/chandrayaan_drivers.py | 203 +++++++++ ...3T20090630T083407_V03_L1B_cropped_pds3.lbl | 178 ++++++++ .../M3T20090630T083407_V03_TIM_cropped.TAB | 5 + .../data/isds/chandrayaan_m3_nadir_isd.json | 418 ++++++++++++++++++ tests/pytests/test_chandrayaan_driver.py | 70 ++- 5 files changed, 867 insertions(+), 7 deletions(-) create mode 100644 tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_L1B_cropped_pds3.lbl create mode 100644 tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_TIM_cropped.TAB create mode 100644 tests/pytests/data/isds/chandrayaan_m3_nadir_isd.json diff --git a/ale/drivers/chandrayaan_drivers.py b/ale/drivers/chandrayaan_drivers.py index 86bb108..a98f874 100644 --- a/ale/drivers/chandrayaan_drivers.py +++ b/ale/drivers/chandrayaan_drivers.py @@ -3,8 +3,211 @@ import spiceypy as spice from ale.base import Driver from ale.base.data_naif import NaifSpice from ale.base.label_isis import IsisLabel +from ale.base.label_pds3 import Pds3Label from ale.base.type_distortion import NoDistortion, ChandrayaanMrffrDistortion from ale.base.type_sensor import LineScanner, Radar +from csv import reader + + +class Chandrayaan1M3Pds3NaifSpiceDriver(LineScanner, Pds3Label, NaifSpice, NoDistortion, Driver): + + @property + def ikid(self): + """ + Returns the Naif ID code for the Moon Mineralogy Mapper + + Returns + ------- + : int + Naif ID used to for identifying the instrument in Spice kernels + """ + return -86520 + + @property + def sensor_frame_id(self): + """ + Returns the Naif ID code for the sensor reference frame + + Returns + ------- + : int + Naif ID code for the sensor frame + """ + return spice.bods2c("CH1") + + + @property + def spacecraft_name(self): + """ + Returns the name of the spacecraft + + Returns + ------- + : str + Full name of the spacecraft + """ + return self.label['MISSION_ID'] + + + @property + def platform_name(self): + """ + Returns the name of the platform. For M3, this is reflected by the mission name. + + Returns + ------- + : str + Name of the platform that the sensor is on + """ + return self.label['MISSION_NAME'] + + + @property + def image_lines(self): + """ + Return the number of lines in the image. + + Returns + ------- + : int + Number of lines in the image + """ + return self.label.get('RDN_FILE').get('RDN_IMAGE').get('LINES') + + + @property + def image_samples(self): + """ + Return the number of samples in the image. + + Returns + ------- + : int + Number of samples in the image + """ + return self.label.get('RDN_FILE').get('RDN_IMAGE').get('LINE_SAMPLES') + + + def read_timing_data(self): + """ + Read data from the timing file. + + Returns + ------- + None + """ + if hasattr(self, '_utc_times'): + return(self._lines, self._utc_times) + + # Read timing file as structured text. Reads each row as a list. + with open(self.utc_time_table, 'r') as time_file: + lists = list(reader(time_file, skipinitialspace=True, delimiter=" ")) + + # Transpose such that each column is a list. Unpack and ignore anything that's not lines and times. + self._lines, self._utc_times, *_ = zip(*lists) + + + @property + def ephemeris_start_time(self): + """ + Returns + ------- + : double + The start time of the image in ephemeris seconds past the J2000 epoch. + """ + if not hasattr(self, '_ephemeris_start_time'): + et = spice.utc2et(self.utc_times[0]) + et -= (.5 * self.line_exposure_duration) + clock_time = spice.sce2s(self.sensor_frame_id, et) + self._ephemeris_start_time = spice.scs2e(self.sensor_frame_id, clock_time) + return self._ephemeris_start_time + + + @property + def ephemeris_stop_time(self): + """ + Returns + ------- + : double + The stop time of the image in ephemeris seconds past the J2000 epoch. + """ + return self.ephemeris_start_time + (self.image_lines * self.exposure_duration) + + + @property + def utc_time_table(self): + """ + Returns + ------- + : str + The name of the file containing the line timing information + """ + if not hasattr(self, '_utc_time_table'): + self._utc_time_table = self.label['UTC_FILE']['^UTC_TIME_TABLE'] + return self._utc_time_table + + + @property + def utc_times(self): + """ UTC time of the center of each line + """ + if not hasattr(self, '_utc_times'): + self.read_timing_data() + + if self._utc_times[0] > self._utc_times[-1]: + return list(reversed(self._utc_times)) + return self._utc_times + + + @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. + + Information found in M3 SIS + + Returns + ------- + : int + Number of samples and lines combined from the original data to produce a single pixel in this image + """ + instrument_mode = self.label['INSTRUMENT_MODE_ID'] + if instrument_mode.upper() == "GLOBAL": + return 2 + else: + return 1 + + + @property + def line_exposure_duration(self): + """ + Line exposure duration returns the time between the exposures for + subsequent lines. + + Logic found in ISIS translation file "Chandrayaan1M3Instrument.trn" + + Returns + ------- + : float + Returns the line exposure duration in seconds from the PDS3 label. + """ + instrument_mode = self.label['INSTRUMENT_MODE_ID'] + if instrument_mode.upper() == "GLOBAL": + return .10176 + elif instrument_mode.upper() == "TARGET": + return .05088 + + @property + def sensor_model_version(self): + """ + Returns + ------- + : int + version of the sensor model + """ + return 1 class Chandrayaan1M3IsisLabelNaifSpiceDriver(LineScanner, IsisLabel, NaifSpice, NoDistortion, Driver): diff --git a/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_L1B_cropped_pds3.lbl b/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_L1B_cropped_pds3.lbl new file mode 100644 index 0000000..59c2369 --- /dev/null +++ b/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_L1B_cropped_pds3.lbl @@ -0,0 +1,178 @@ +PDS_VERSION_ID = PDS3 +LABEL_REVISION_NOTE = "2009-01-26, S. Lundeen, 2010-12-07, S. Lundeen, 2011-09-20, S. Lundeen" +DATA_SET_ID = CH1-ORB-L-M3-4-L1B-RADIANCE-V3.0 +PRODUCT_ID = M3T20090630T083407_V03_RDN +RECORD_TYPE = UNDEFINED +MISSION_ID = CH1 +MISSION_NAME = CHANDRAYAAN-1 +INSTRUMENT_HOST_ID = CH1-ORB +INSTRUMENT_HOST_NAME = "CHANDRAYAAN-1 ORBITER" +INSTRUMENT_NAME = "MOON MINERALOGY MAPPER" +INSTRUMENT_ID = M3 +TARGET_NAME = MOON +TARGET_TYPE = SATELLITE +MISSION_PHASE_NAME = "PRIMARY MISSION" +PRODUCT_TYPE = CALIBRATED_IMAGE +PRODUCT_CREATION_TIME = 2009-05-10T18:01:10 +START_TIME = 2009-06-30T08:34:07 +STOP_TIME = 2009-06-30T08:34:36 +SPACECRAFT_CLOCK_START_COUNT = 12/1759028.348 +SPACECRAFT_CLOCK_STOP_COUNT = 12/1759056.993 +ORBIT_NUMBER = 2804 +PRODUCT_VERSION_TYPE = ACTUAL +PRODUCT_VERSION_ID = "3.0" +SOURCE_PRODUCT_ID = M3T20090630T083407_V01_L0.IMG +PRODUCER_INSTITUTION_NAME = "JET PROPULSION LABORATORY" +SOFTWARE_NAME = m3t_l1b_v07.exe +SOFTWARE_VERSION_ID = "07" +DESCRIPTION = "M3 Level 1B data product which contains pixel located, radiometrically-calibrated data." +SOLAR_DISTANCE = 1.01711556761 <AU> +INSTRUMENT_MODE_ID = TARGET +DETECTOR_TEMPERATURE = 161.99 +CH1:SWATH_WIDTH = 608 <pixel> +CH1:SWATH_LENGTH = 564 <pixel> +CH1:SPACECRAFT_YAW_DIRECTION = FORWARD +CH1:ORBIT_LIMB_DIRECTION = ASCENDING +SPACECRAFT_ORIENTATION = (N/A, N/A, N/A) +CH1:INITIAL_SC_ORIENTATION = (0.233580805487, 2.281265294933, 4.003902254047) +CH1:SC_ORIENTATION_EPOCH_TDB_TIME = 299617824.351 +CH1:SC_ORIENTATION_RATE = (N/A, N/A, N/A) +CH1:SC_ROTATION_AXIS_VECTOR = (0.049715054267, -0.997329135941, 0.053507083471) +CH1:SC_ROTATION_RATE = 0.046843426581 +^DESCRIPTION = L1B_NAV_DESC.ASC +CH1:SPECTRAL_CALIBRATION_FILE_NAME = M3T20070912_RDN_SPC.TAB +CH1:RAD_GAIN_FACTOR_FILE_NAME = M3T20070912_RDN_GAIN.TAB +Object = RDN_FILE + ^RDN_IMAGE = M3T20090630T083407_V03_RDN_cropped.IMG + RECORD_TYPE = FIXED_LENGTH + RECORD_BYTES = 7296 + FILE_RECORDS = 5 + Object = RDN_IMAGE + LINES = 5 + LINE_SAMPLES = 608 + SAMPLE_TYPE = PC_REAL + SAMPLE_BITS = 32 + UNIT = "W/(m^2 um sr)" + BANDS = 3 + BAND_STORAGE_TYPE = LINE_INTERLEAVED + LINE_DISPLAY_DIRECTION = DOWN + SAMPLE_DISPLAY_DIRECTION = RIGHT + End_Object +End_Object +Object = RDN_HDR_FILE + ^RDN_ENVI_HEADER = M3T20090630T083407_V03_RDN.HDR + RECORD_TYPE = VARIABLE_LENGTH + FILE_RECORDS = 803 + Object = RDN_ENVI_HEADER + INTERCHANGE_FORMAT = ASCII + BYTES = 25037 + HEADER_TYPE = ENVI + DESCRIPTION = "Header file for compatibility with the commercial software package ENVI." + End_Object +End_Object +Object = LOC_FILE + ^LOC_IMAGE = M3T20090630T083407_V03_LOC_cropped.IMG + RECORD_TYPE = FIXED_LENGTH + RECORD_BYTES = 14592 + FILE_RECORDS = 5 + Object = LOC_IMAGE + LINES = 5 + LINE_SAMPLES = 608 + SAMPLE_TYPE = PC_REAL + SAMPLE_BITS = 64 + BANDS = 3 + BAND_STORAGE_TYPE = LINE_INTERLEAVED + BAND_NAME = (Longitude, Latitude, Radius) + LINE_DISPLAY_DIRECTION = DOWN + SAMPLE_DISPLAY_DIRECTION = RIGHT + End_Object +End_Object +Object = LOC_HDR_FILE + ^LOC_ENVI_HEADER = M3T20090630T083407_V03_LOC.HDR + RECORD_TYPE = VARIABLE_LENGTH + FILE_RECORDS = 16 + Object = LOC_ENVI_HEADER + INTERCHANGE_FORMAT = ASCII + BYTES = 371 + HEADER_TYPE = ENVI + DESCRIPTION = "Header file for compatibility with the commercial software package ENVI." + End_Object +End_Object +Object = OBS_FILE + ^OBS_IMAGE = M3T20090630T083407_V03_OBS_cropped.IMG + RECORD_TYPE = FIXED_LENGTH + RECORD_BYTES = 24320 + FILE_RECORDS = 5 + Object = OBS_IMAGE + LINES = 5 + LINE_SAMPLES = 608 + SAMPLE_TYPE = PC_REAL + SAMPLE_BITS = 32 + BANDS = 10 + BAND_STORAGE_TYPE = LINE_INTERLEAVED + BAND_NAME = ("To-Sun AZM", "To-Sun Zenith", "To-Inst AZM", "To-Inst Zenith", Phase-angle, "To-Sun Path Length", "To-Inst Path Length", "Facet Slope", "Facet Aspect", "Facet Cos i") + LINE_DISPLAY_DIRECTION = DOWN + SAMPLE_DISPLAY_DIRECTION = RIGHT + End_Object +End_Object +Object = OBS_HDR_FILE + ^OBS_ENVI_HEADER = M3T20090630T083407_V03_OBS.HDR + RECORD_TYPE = VARIABLE_LENGTH + FILE_RECORDS = 21 + Object = OBS_ENVI_HEADER + INTERCHANGE_FORMAT = ASCII + BYTES = 706 + HEADER_TYPE = ENVI + DESCRIPTION = "Header file for compatibility with the commercial software package ENVI." + End_Object +End_Object +Object = UTC_FILE + ^UTC_TIME_TABLE = M3T20090630T083407_V03_TIM_cropped.TAB + RECORD_TYPE = FIXED_LENGTH + RECORD_BYTES = 57 + FILE_RECORDS = 5 + Object = UTC_TIME_TABLE + NAME = "UTC OBSERVATION TIMING DATA" + INTERCHANGE_FORMAT = ASCII + ROWS = 5 + COLUMNS = 4 + ROW_BYTES = 57 + Object = COLUMN + COLUMN_NUMBER = 1 + NAME = "LINE NUMBER" + DATA_TYPE = ASCII_INTEGER + START_BYTE = 1 + BYTES = 6 + FORMAT = I6 + DESCRIPTION = "Record number for each RDN image line" + End_Object + Object = COLUMN + COLUMN_NUMBER = 2 + NAME = UTC_TIME + DATA_TYPE = TIME + START_BYTE = 8 + BYTES = 26 + FORMAT = A26 + DESCRIPTION = "UTC Time for the middle of the integration period for each RDN image line expressed as YYYY-MM-DDTHH:MM:SS.SSSSSS" + End_Object + Object = COLUMN + COLUMN_NUMBER = 3 + NAME = YEAR + DATA_TYPE = CHARACTER + START_BYTE = 35 + BYTES = 4 + FORMAT = I4 + DESCRIPTION = "Decimal Day of Year (DDOY) Year reference extracted from the earliest time of each RDN image line" + End_Object + Object = COLUMN + COLUMN_NUMBER = 4 + NAME = DDOY + DATA_TYPE = DATE + START_BYTE = 40 + BYTES = 16 + FORMAT = F16.12 + DESCRIPTION = "Decimal Day of Year represented as the number of days elapsed since 00:00 UTC of January 1 of the year associated with the time stamp of the first line of the RDN image file. DDOY is expressed using seventeen characters where 1-3 = three characters that contain the integer number of days; 4 = a decimal point; 5-16 = twelve charact- ers after the decimal for the fractional part of the day of year value." + End_Object + End_Object +End_Object +End \ No newline at end of file diff --git a/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_TIM_cropped.TAB b/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_TIM_cropped.TAB new file mode 100644 index 0000000..0932173 --- /dev/null +++ b/tests/pytests/data/M3T20090630T083407_V03_RDN/M3T20090630T083407_V03_TIM_cropped.TAB @@ -0,0 +1,5 @@ + 1 2009-06-30T08:34:35.653371 2009 180.357357101487 + 2 2009-06-30T08:34:35.602491 2009 180.357356512598 + 3 2009-06-30T08:34:35.551611 2009 180.357355923710 + 4 2009-06-30T08:34:35.500731 2009 180.357355334822 + 5 2009-06-30T08:34:35.449851 2009 180.357354745933 diff --git a/tests/pytests/data/isds/chandrayaan_m3_nadir_isd.json b/tests/pytests/data/isds/chandrayaan_m3_nadir_isd.json new file mode 100644 index 0000000..bf80f20 --- /dev/null +++ b/tests/pytests/data/isds/chandrayaan_m3_nadir_isd.json @@ -0,0 +1,418 @@ + { + "isis_camera_version": 1, + "image_lines": 5, + "image_samples": 608, + "name_platform": "CHANDRAYAAN-1", + "name_sensor": "MOON MINERALOGY MAPPER", + "reference_height": { + "maxheight": 1000, + "minheight": -1000, + "unit": "m" + }, + "name_model": "USGS_ASTRO_LINE_SCANNER_SENSOR_MODEL", + "interpolation_method": "lagrange", + "line_scan_rate": [ + [ + 0.5, + -0.12720000743865967, + 0.05088 + ] + ], + "starting_ephemeris_time": 299622941.60814995, + "center_ephemeris_time": 299622941.73534995, + "radii": { + "semimajor": 1737.4, + "semiminor": 1737.4, + "unit": "km" + }, + "body_rotation": { + "time_dependent_frames": [ + 31006, + 1 + ], + "ck_table_start_time": 299622941.60814995, + "ck_table_end_time": 299622941.86254996, + "ck_table_original_size": 2, + "ephemeris_times": [ + 299622941.60814995, + 299622941.86254996 + ], + "quaternions": [ + [ + -0.9747735513065916, + 0.19646555501476617, + -0.009172349392417702, + 0.1055162422212761 + ], + [ + -0.9747735156174205, + 0.196465551731104, + -0.009172415802241563, + 0.10551657226330902 + ] + ], + "angular_velocities": [ + [ + 6.124937754497467e-08, + -1.0239801705539717e-06, + 2.4560118095097265e-06 + ], + [ + 6.12493776573662e-08, + -1.0239801709466094e-06, + 2.456011809503279e-06 + ] + ], + "constant_frames": [ + 31001, + 31007, + 31006 + ], + "constant_rotation": [ + 0.9999998732547144, + -0.00032928542237557133, + 0.00038086961867138755, + 0.00032928600021094723, + 0.9999999457843062, + -1.4544409378362713e-06, + -0.00038086911909607826, + 1.5798557868269087e-06, + 0.9999999274681067 + ], + "reference_frame": 1 + }, + "instrument_pointing": { + "time_dependent_frames": [ + -86, + 1 + ], + "ck_table_start_time": 299622941.60814995, + "ck_table_end_time": 299622941.86254996, + "ck_table_original_size": 6, + "ephemeris_times": [ + 299622941.60814995, + 299622941.65902996, + 299622941.70991, + 299622941.76078993, + 299622941.81166995, + 299622941.86254996 + ], + "quaternions": [ + [ + 0.04661238772647475, + -0.692389430047604, + 0.7198383853973618, + -0.01602689543580429 + ], + [ + 0.04659829485244615, + -0.692423944862404, + 0.719806464803485, + -0.0160103942843507 + ], + [ + 0.046584207173847626, + -0.6924585919315193, + 0.7197744130572963, + -0.015993886651673537 + ], + [ + 0.04657012448653539, + -0.6924933610486642, + 0.7197422399398765, + -0.01597737322473273 + ], + [ + 0.046556047309271195, + -0.6925282769138067, + 0.7197099216524531, + -0.01596085238170966 + ], + [ + 0.046541973820848646, + -0.692563256361473, + 0.719677538184117, + -0.01594432952811621 + ] + ], + "angular_velocities": null, + "reference_frame": 1, + "constant_frames": [ + -86 + ], + "constant_rotation": [ + 1.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + "naif_keywords": { + "BODY301_RADII": [ + 1737.4, + 1737.4, + 1737.4 + ], + "BODY_FRAME_CODE": 31001, + "BODY_CODE": 301, + "INS-86520_ITRANSS": [ + -1.9610889460163698, + -0.054945530371164404, + -37.036996280362 + ], + "INS-86520_BORESIGHT_SAMPLE": 304.5, + "TKFRAME_-86520_RELATIVE": "CH1_SPACECRAFT", + "INS-86520_OD_K": [ + 0.000379921103637315, + 0.000213226448051461, + -4.0186287875859195e-08 + ], + "FRAME_-86520_CLASS": 4.0, + "INS-86520_DECENTER": [ + 0.004047, + -5e-06 + ], + "INS-86520_CK_REFERENCE_ID": 1.0, + "INS-86520_PLATFORM_ID": -86000.0, + "TKFRAME_-86520_UNITS": "DEGREES", + "INS-86520_LT_SURFACE_CORRECT": "TRUE", + "INS-86520_SWAP_OBSERVER_TARGET": "TRUE", + "TKFRAME_-86520_ANGLES": [ + 0.0, + 0.0, + 0.0 + ], + "FRAME_-86520_CENTER": -86.0, + "INS-86520_LIGHTTIME_CORRECTION": "NONE", + "INS-86520_PIXEL_PITCH": 0.027, + "FRAME_-86520_NAME": "CHANDRAYAAN-1_M3", + "TKFRAME_-86520_AXES": [ + 1.0, + 2.0, + 3.0 + ], + "TKFRAME_-86520_SPEC": "ANGLES", + "INS-86520_TRANSX": [ + -0.64, + -4.00552916405788e-05, + 0.0269999702883839 + ], + "INS-86520_TRANSY": [ + -0.052, + -0.0269999702883839, + -4.00552916405788e-05 + ], + "FRAME_-86520_CLASS_ID": -86520.0, + "INS-86520_CK_FRAME_ID": -86000.0, + "INS-86520_BORESIGHT_LINE": 0.0, + "INS-86520_FOCAL_LENGTH": 39.63, + "INS-86520_PP": [ + 0.0, + 0.0 + ], + "INS-86520_ITRANSL": [ + 23.7008204518524, + 37.036996280362, + -0.054945530371164404 + ], + "BODY301_POLE_RA": [ + 269.9949, + 0.0031, + 0.0 + ], + "BODY301_NUT_PREC_PM": [ + 3.561, + 0.1208, + -0.0642, + 0.0158, + 0.0252, + -0.0066, + -0.0047, + -0.0046, + 0.0028, + 0.0052 + ], + "BODY301_NUT_PREC_RA": [ + -3.8787000000000003, + -0.1204, + 0.07, + -0.0172, + 0.0, + 0.0072, + 0.0, + 0.0, + 0.0, + -0.0052 + ], + "BODY301_LONG_AXIS": 0.0, + "BODY301_NUT_PREC_DEC": [ + 1.5419, + 0.0239, + -0.0278, + 0.0068, + 0.0, + -0.0029, + 0.0009, + 0.0, + 0.0, + 0.0008 + ], + "BODY301_POLE_DEC": [ + 66.5392, + 0.013, + 0.0 + ], + "BODY301_PM": [ + 38.3213, + 13.17635815, + -1.3999999999999999e-12 + ] + }, + "detector_sample_summing": 1, + "detector_line_summing": 1, + "focal_length_model": { + "focal_length": 39.63 + }, + "detector_center": { + "line": 0.0, + "sample": 304.5 + }, + "focal2pixel_lines": [ + 23.7008204518524, + 37.036996280362, + -0.054945530371164404 + ], + "focal2pixel_samples": [ + -1.9610889460163698, + -0.054945530371164404, + -37.036996280362 + ], + "optical_distortion": { + "radial": { + "coefficients": [ + 0.0, + 0.0, + 0.0 + ] + } + }, + "starting_detector_line": 0, + "starting_detector_sample": 0, + "instrument_position": { + "spk_table_start_time": 299622941.60814995, + "spk_table_end_time": 299622941.86254996, + "spk_table_original_size": 6, + "ephemeris_times": [ + 299622941.60814995, + 299622941.65902996, + 299622941.70991, + 299622941.76078993, + 299622941.81166995, + 299622941.86254996 + ], + "positions": [ + [ + 87.43803283072197, + 170.58382785758494, + 1937.3684802589921 + ], + [ + 87.43510506145041, + 170.50391417711066, + 1937.376298445722 + ], + [ + 87.43218518920048, + 170.4240123258735, + 1937.3841107949738 + ], + [ + 87.4292732456229, + 170.3441224440555, + 1937.3919172883918 + ], + [ + 87.4263692523569, + 170.26424439143344, + 1937.3997179348762 + ], + [ + 87.42347324097759, + 170.1843783074444, + 1937.4075127164094 + ] + ], + "velocities": [ + [ + -0.05762002410373986, + -1.5707459933015884, + 0.1537165891795824 + ], + [ + -0.05746510464971223, + -1.5705139595334539, + 0.15360195064617482 + ], + [ + -0.057309612713474595, + -1.5702809919217755, + 0.15348712189339614 + ], + [ + -0.05715359501889533, + -1.5700471605505897, + 0.15337213718299325 + ], + [ + -0.05699694014477726, + -1.5698122982929306, + 0.15325691481115888 + ], + [ + -0.05684002521205642, + -1.569576970816976, + 0.15314173131322809 + ] + ], + "reference_frame": 1 + }, + "sun_position": { + "spk_table_start_time": 299622941.60814995, + "spk_table_end_time": 299622941.86254996, + "spk_table_original_size": 2, + "ephemeris_times": [ + 299622941.60814995, + 299622941.86254996 + ], + "positions": [ + [ + -22279392.552556925, + 138086311.0772047, + 59901634.029351056 + ], + [ + -22279399.993010454, + 138086310.29030323, + 59901633.69455383 + ] + ], + "velocities": [ + [ + -29.247063783209654, + -3.0931654356540093, + -1.3160264669418211 + ], + [ + -29.24706420755107, + -3.0931669393224728, + -1.3160271856310302 + ] + ], + "reference_frame": 1 + } +} \ No newline at end of file diff --git a/tests/pytests/test_chandrayaan_driver.py b/tests/pytests/test_chandrayaan_driver.py index 637d7cb..25ad058 100644 --- a/tests/pytests/test_chandrayaan_driver.py +++ b/tests/pytests/test_chandrayaan_driver.py @@ -2,17 +2,13 @@ from cgi import test import pytest import ale import os -import pvl -import numpy as np -from ale.drivers import co_drivers -from ale.formatters.formatter import to_isd import unittest -from unittest.mock import PropertyMock, patch +from unittest.mock import patch import json -from conftest import get_image_label, get_image_kernels, get_isd, convert_kernels, compare_dicts, get_table_data +from conftest import get_image_label, get_image_kernels, get_isd, convert_kernels, compare_dicts -from ale.drivers.chandrayaan_drivers import Chandrayaan1M3IsisLabelNaifSpiceDriver, Chandrayaan1MRFFRIsisLabelNaifSpiceDriver +from ale.drivers.chandrayaan_drivers import Chandrayaan1M3IsisLabelNaifSpiceDriver, Chandrayaan1MRFFRIsisLabelNaifSpiceDriver, Chandrayaan1M3Pds3NaifSpiceDriver @pytest.fixture() def m3_kernels(scope="module", autouse=True): @@ -48,6 +44,66 @@ def test_chandrayaan_mrffr_load(mrffr_kernels): x = compare_dicts(isd_obj, compare_dict) assert x == [] +def test_chandrayaan_m3_pds_load(m3_kernels): + label_file = get_image_label("M3T20090630T083407_V03_L1B_cropped", label_type="pds3") + compare_dict = get_isd("chandrayaan_m3_nadir") + + # Patch the full path of the timing table onto the driver + with patch("ale.drivers.chandrayaan_drivers.Chandrayaan1M3Pds3NaifSpiceDriver.utc_time_table", os.path.dirname(label_file)+"/M3T20090630T083407_V03_TIM_cropped.TAB"): + isd_str = ale.loads(label_file, props={"kernels": m3_kernels, "nadir": True}) + isd_obj = json.loads(isd_str) + x = compare_dicts(isd_obj, compare_dict) + assert x == [] + + +class test_chandrayaan_m3_pds_naif(unittest.TestCase): + + def setUp(self): + label = get_image_label("M3T20090630T083407_V03_L1B_cropped", "pds3") + self.driver = Chandrayaan1M3Pds3NaifSpiceDriver(label) + + def test_ikid(self): + assert self.driver.ikid == -86520 + + def test_sensor_frame_id(self): + assert self.driver.sensor_frame_id == -86 + + def test_spacecraft_name(self): + assert self.driver.spacecraft_name == 'CH1' + + def test_image_lines(self): + assert self.driver.image_lines == 5 + + def test_image_samples(self): + assert self.driver.image_samples == 608 + + def test_ephemeris_start_time(self): + label_file = get_image_label("M3T20090630T083407_V03_L1B_cropped", label_type="pds3") + with patch("ale.drivers.chandrayaan_drivers.spice.scs2e", return_value=12345) as scs2e,\ + patch("ale.drivers.chandrayaan_drivers.spice.utc2et", return_value=12345) as utc2et,\ + patch("ale.drivers.chandrayaan_drivers.spice.sce2s", return_value=12345) as sce2s,\ + patch("ale.drivers.chandrayaan_drivers.Chandrayaan1M3Pds3NaifSpiceDriver.utc_time_table", os.path.dirname(label_file)+"/M3T20090630T083407_V03_TIM_cropped.TAB"): + assert self.driver.ephemeris_start_time == 12345 + + def test_ephemeris_stop_time(self): + label_file = get_image_label("M3T20090630T083407_V03_L1B_cropped", label_type="pds3") + with patch("ale.drivers.chandrayaan_drivers.spice.scs2e", return_value=12345) as scs2e,\ + patch("ale.drivers.chandrayaan_drivers.spice.utc2et", return_value=12345) as utc2et,\ + patch("ale.drivers.chandrayaan_drivers.spice.sce2s", return_value=12345) as sce2s,\ + patch("ale.drivers.chandrayaan_drivers.Chandrayaan1M3Pds3NaifSpiceDriver.utc_time_table", os.path.dirname(label_file)+"/M3T20090630T083407_V03_TIM_cropped.TAB"): + assert self.driver.ephemeris_stop_time == 12345.2544 + + def test_utc_times(self): + label_file = get_image_label("M3T20090630T083407_V03_L1B_cropped", label_type="pds3") + with patch("ale.drivers.chandrayaan_drivers.Chandrayaan1M3Pds3NaifSpiceDriver.utc_time_table", os.path.dirname(label_file)+"/M3T20090630T083407_V03_TIM_cropped.TAB"): + assert self.driver.utc_times[0] == '2009-06-30T08:34:35.449851' + + def test_sampling_factor(self): + assert self.driver.sampling_factor == 1 + + def test_line_exposure_duration(self): + assert self.driver.line_exposure_duration == .05088 + # ========= Test chandrayaan isislabel and naifspice driver ========= class test_chandrayaan_isis_naif(unittest.TestCase): -- GitLab