Skip to content

Commit

Permalink
M3 PDS3 NaifSpice Driver (#608)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
AustinSanders authored Jun 13, 2024
1 parent ee49225 commit 0ba7b24
Show file tree
Hide file tree
Showing 5 changed files with 867 additions and 7 deletions.
203 changes: 203 additions & 0 deletions ale/drivers/chandrayaan_drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,211 @@
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):

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 0ba7b24

Please sign in to comment.