MillionConcepts / pdr

[P]lanetary [D]ata [R]eader - A single function to read all Planetary Data System (PDS) data into Python
Other
60 stars 6 forks source link

pdr.metadata ignores exponent with PDS3 labels #53

Closed sschmaus closed 9 months ago

sschmaus commented 9 months ago

I'm initializing Mars2020 data from the embedded PDS3 label with pdr v1.0.4.

Here is the PDS3 label:

ODL_VERSION_ID                    = ODL3

/* FILE DATA ELEMENTS */

RECORD_TYPE                       = FIXED_LENGTH
RECORD_BYTES                      = 3296
FILE_RECORDS                      = 1215
LABEL_RECORDS                     = 10
^IMAGE_HEADER                = 11
^IMAGE                       = 16
 ACTIVE_FLIGHT_STRING_ID          = "A"
 COMMAND_SEQUENCE_NUMBER          = 14
 FRAME_ID                         = "LEFT"
 FRAME_TYPE                       = STEREO
 GEOMETRY_PROJECTION_TYPE         = RAW
 IMAGE_ID                         = "510"
 IMAGE_TIME                       = 2023-04-03T13:46:05.234
 IMAGE_TYPE                       = REGULAR
 IMAGE_ACQUIRE_MODE               = IMAGE
 INSTRUMENT_HOST_ID               = "M20"
 INSTRUMENT_HOST_NAME             = "MARS 2020"
 INSTRUMENT_ID                    = "MCZ_LEFT"
 INSTRUMENT_NAME                  = "MAST CAMERA ZOOM LEFT"
 INSTRUMENT_SERIAL_NUMBER         = "4007"
 INSTRUMENT_TYPE                  = "IMAGING CAMERA"
 INSTRUMENT_VERSION_ID            = "FM"
 LOCAL_MEAN_SOLAR_TIME            = "Sol-00753M16:05:57.375"
 LOCAL_TRUE_SOLAR_TIME            = "15:58:02"
 MISSION_NAME                     = "MARS 2020"
 MISSION_PHASE_NAME               = "PRIMARY_SURFACE_MISSION"
 PLANET_DAY_NUMBER                = 753
 LOCAL_TRUE_SOLAR_TIME_SOL        = "753"
 PRODUCER_INSTITUTION_NAME        = 
"MASTCAMZ TEAM, ARIZONA STATE UNIVERSITY"
 PRODUCT_CREATION_TIME            = 2023-06-14T06:49:35.090
 PRODUCT_VERSION_ID               = "V4.0 MATLAB"
 RELEASE_ID                       = "0004"
 REQUEST_ID                       = "0"
 ROVER_MOTION_COUNTER             = (37,1798,10,0,0,0,40,0,0,0)
 ROVER_MOTION_COUNTER_NAME        = ("SITE","DRIVE","POSE","ARM","SHA",
                                     "DRILL","RSM","HGA","BITCAR","SEAL")
 SEQUENCE_ID                      = "zcam08758"
 SEQUENCE_VERSION_ID              = "0"
 SOLAR_LONGITUDE                  = 45.9431
 SPACECRAFT_CLOCK_CNT_PARTITION   = 1
 SPACECRAFT_CLOCK_START_COUNT     = "733800948.452"
 SPACECRAFT_CLOCK_STOP_COUNT      = "733800948.470"
 START_TIME                       = 2023-04-03T13:46:05.234
 STOP_TIME                        = 2023-04-03T13:46:05.234
 TARGET_NAME                      = "MARS"
 TARGET_TYPE                      = PLANET
 UNITS                            = "W/M^2/SR/NM"
 CAMERA_PRODUCT_ID                = "510"
 TRACKING_ID                      = "1008758005"
 SOURCE_PRODUCT_ID                = 
"ZL0_0753_0733800936_770EDR_N0371798ZCAM08758_1100LMJ01"
 PRODUCT_ID                       = 
"ZL0_0753_0733800936_770RAD_N0371798ZCAM08758_1100LMA01"
 APPLICATION_PROCESS_ID           = 677
 APPLICATION_PROCESS_NAME         = "MczLImage"
 EARTH_RECEIVED_START_TIME        = 2023-04-04T05:52:27.272
 EARTH_RECEIVED_STOP_TIME         = 2023-04-04T05:52:44.089
 EXPECTED_PACKETS                 = 111
 RECEIVED_PACKETS                 = 111
 SPICE_FILE_NAME                  = "chronos.m2020_ops210303_v1"
 TELEMETRY_PROVIDER_ID            = "MPCS_M2020_DP"
 TELEMETRY_SOURCE_HOST_NAME       = "m20-sops-control-1"
 TELEMETRY_SOURCE_NAME            = "MczLImage_0733800936-50675-1.dat"
 TELEMETRY_SOURCE_TYPE            = "DATA PRODUCT"
 COMMUNICATION_SESSION_ID         = "57540"
 DOWNLOAD_PRIORITY                = 88
 EXPECTED_TRANSMISSION_PATH       = "128"
 FLIGHT_SOFTWARE_MODE             = "8"
 FLIGHT_SOFTWARE_VERSION_ID       = "442959749"
 PRODUCT_COMPLETION_STATUS        = COMPLETE_CHECKSUM_PASS
 PRODUCT_TAG                      = "1"
 SEQUENCE_EXECUTION_COUNT         = 1
 TELEMETRY_SOURCE_SIZE            = 1119183
 TELEMETRY_SOURCE_CHECKSUM        = 44016
 TELEMETRY_SOURCE_START_TIME      = 2023-093T13:45:54.000Z
 TELEMETRY_SOURCE_SCLK_START      = "733800936.773"
 AUTO_DELETE_FLAG                 = "FALSE"
 TRANSMISSION_PATH                = "0"
 VIRTUAL_CHANNEL_ID               = "0"
 IMAGE_DATA_SIZE                  = 1977664
 BOOT_COUNT                       = 4015
 COMMAND_DISPATCH_SCLK            = 733800936.50510
 DATA_PRODUCT_COMPRESSION_TYPE    = Uncompressed

/* HISTORY DATA ELEMENTS */

 GROUP                            = PDS_HISTORY
   SOFTWARE_NAME                  = "CWGRADCAL04"
   SOFTWARE_VERSION_ID            = "V4.1 12-16-2022"
   PROCESSING_HISTORY_TEXT        = "EDR TO RAD"
 END_GROUP                        = PDS_HISTORY

/* CAMERA_MODEL DATA ELEMENTS */

GROUP                             = GEOMETRIC_CAMERA_MODEL
  CALIBRATION_SOURCE_ID           = "1"
  MODEL_TYPE                      = CAHVOR
  MODEL_COMPONENT_ID              = ("C","A","H","V","O","R")
  MODEL_COMPONENT_NAME            = ("CENTER","AXIS","HORIZONTAL",
                                     "VERTICAL","OPTICAL","RADIAL")
  MODEL_COMPONENT_UNIT            = (METER,"N/A",PIXEL,PIXEL,"N/A","N/A")
  MODEL_COMPONENT_1               = (0.926423,0.530902,-1.98623)
  MODEL_COMPONENT_2               = (0.314049,0.946128,-0.0789417)
  MODEL_COMPONENT_3               = (-13920.7,5406.19,-138.652)
  MODEL_COMPONENT_4               = (513.99,1841.24,14809.2)
  MODEL_COMPONENT_5               = (0.308175,0.946545,-0.0953799)
  MODEL_COMPONENT_6               = (0.000228222,0.448558,0.0902153)
  MODEL_TRANSFORM_VECTOR          = (0.804988,0.559508,-1.91903)
  MODEL_TRANSFORM_QUATERNION      = (0.81372,-0.0281662,0.0383972,0.579303)
  REFERENCE_COORD_SYSTEM_NAME     = "ROVER_NAV_FRAME"
  REFERENCE_COORD_SYSTEM_INDEX    = (37,1798,10)
  INTERPOLATION_METHOD            = ZOOM
  INTERPOLATION_VALUE             = 9600.0
END_GROUP                         = GEOMETRIC_CAMERA_MODEL

/* COORDINATE SYSTEM STATE: ROVER */

GROUP                             = ROVER_COORDINATE_SYSTEM
  SOLUTION_ID                     = "TELEMETRY"
  COORDINATE_SYSTEM_NAME          = "ROVER_NAV_FRAME"
  COORDINATE_SYSTEM_INDEX         = (37,1798,10,0,0,0,40,0,0,0)
  COORDINATE_SYSTEM_INDEX_NAME    = ("SITE","DRIVE","POSE","ARM","SHA",
                                     "DRILL","RSM","HGA","BITCAR","SEAL")
  ORIGIN_OFFSET_VECTOR            = (7.82134,-265.441,-7.39865)
  ORIGIN_ROTATION_QUATERNION      = (0.965268,0.0156119,-0.0634516,0.252957)
  POSITIVE_AZIMUTH_DIRECTION      = CLOCKWISE
  POSITIVE_ELEVATION_DIRECTION    = UP
  QUATERNION_MEASUREMENT_METHOD   = FINE
  REFERENCE_COORD_SYSTEM_NAME     = "SITE_FRAME"
  REFERENCE_COORD_SYSTEM_INDEX    = 37
  ATTITUDE_PROPAGATION_COUNTER    = 0.0
  ATTITUDE_PROPAGATION_DURATION   = 0.0
END_GROUP                         = ROVER_COORDINATE_SYSTEM

/* COORDINATE SYSTEM STATE: REMOTE SENSING MAST */

GROUP                             = RSM_COORDINATE_SYSTEM
  SOLUTION_ID                     = "TELEMETRY"
  COORDINATE_SYSTEM_NAME          = "RSM_HEAD_FRAME"
  COORDINATE_SYSTEM_INDEX         = (37,1798,10,0,0,0,40,0,0,0)
  COORDINATE_SYSTEM_INDEX_NAME    = ("SITE","DRIVE","POSE","ARM","SHA",
                                     "DRILL","RSM","HGA","BITCAR","SEAL")
  ORIGIN_OFFSET_VECTOR            = (0.804988,0.559508,-1.91903)
  ORIGIN_ROTATION_QUATERNION      = (0.81372,-0.0281662,0.0383972,0.579303)
  POSITIVE_AZIMUTH_DIRECTION      = CLOCKWISE
  POSITIVE_ELEVATION_DIRECTION    = UP
  REFERENCE_COORD_SYSTEM_NAME     = "ROVER_NAV_FRAME"
  REFERENCE_COORD_SYSTEM_INDEX    = (37,1798,10,0,0,0,40,0,0,0)
END_GROUP                         = RSM_COORDINATE_SYSTEM

/* COORDINATE SYSTEM STATE: TURRET */

GROUP                             = TURRET_COORDINATE_SYSTEM
  SOLUTION_ID                     = "TELEMETRY"
  COORDINATE_SYSTEM_NAME          = "ARM_TURRET_FRAME"
  COORDINATE_SYSTEM_INDEX         = (37,1798,10,0,0,0,40,0,0,0)
  COORDINATE_SYSTEM_INDEX_NAME    = ("SITE","DRIVE","POSE","ARM","SHA",
                                     "DRILL","RSM","HGA","BITCAR","SEAL")
  ORIGIN_OFFSET_VECTOR            = (1.08577,-0.429048,-1.40274)
  ORIGIN_ROTATION_QUATERNION      = (0.997148,-0.00157019,0.00028285,
                                     0.075454)
  POSITIVE_AZIMUTH_DIRECTION      = CLOCKWISE
  POSITIVE_ELEVATION_DIRECTION    = UP
  REFERENCE_COORD_SYSTEM_NAME     = "ROVER_NAV_FRAME"
  REFERENCE_COORD_SYSTEM_INDEX    = (37,1798,10,0,0,0,40,0,0)
END_GROUP                         = TURRET_COORDINATE_SYSTEM

/* COORDINATE SYSTEM STATE: TOOL */

GROUP                             = TOOL_COORDINATE_SYSTEM
  SOLUTION_ID                     = "TELEMETRY"
  COORDINATE_SYSTEM_NAME          = "ARM_PIXL_FRAME"
  COORDINATE_SYSTEM_INDEX         = (37,1798,10,0,0,0,40,0,0,0)
  COORDINATE_SYSTEM_INDEX_NAME    = ("SITE","DRIVE","POSE","ARM","SHA",
                                     "DRILL","RSM","HGA","BITCAR","SEAL")
  ORIGIN_OFFSET_VECTOR            = (1.03194,-0.0754546,-1.41385)
  ORIGIN_ROTATION_QUATERNION      = (0.651736,-0.00091029,0.0013103,0.758444)
  POSITIVE_AZIMUTH_DIRECTION      = CLOCKWISE
  POSITIVE_ELEVATION_DIRECTION    = UP
  REFERENCE_COORD_SYSTEM_NAME     = "ROVER_NAV_FRAME"
  REFERENCE_COORD_SYSTEM_INDEX    = (37,1798,10,0,0,0,40,0,0,0)
END_GROUP                         = TOOL_COORDINATE_SYSTEM

/* ARTICULATION DEVICE STATE: REMOTE SENSING MAST */

GROUP                             = RSM_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "RSM"
  ARTICULATION_DEVICE_NAME        = "REMOTE SENSING MAST"
  ARTICULATION_DEVICE_ANGLE       = (4.3985,1.68318,4.48929,1.68152,4.40292
                                     ,1.68558,4.40293,1.68558,4.49364,
                                     1.68052)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("AZIMUTH FINAL-RESOLVER",
                                     "ELEVATION FINAL-RESOLVER",
                                     "AZIMUTH INITIAL-RESOLVER",
                                     "ELEVATION INITIAL-RESOLVER",
                                     "AZIMUTH REQUESTED",
                                     "ELEVATION REQUESTED",
                                     "AZIMUTH FINAL-ENCODER",
                                     "ELEVATION FINAL-ENCODER",
                                     "AZIMUTH INITIAL-ENCODER",
                                     "ELEVATION INITIAL-ENCODER")
  ARTICULATION_DEVICE_MODE        = DEPLOYED
  ARTICULATION_DEVICE_TEMP        = (-20.253 <degC>,-23.9907 <degC>)
  ARTICULATION_DEVICE_TEMP_NAME   = ("NAVCAM LEFT CAMERA PLATE",
                                     "NAVCAM RIGHT CAMERA PLATE")
END_GROUP                         = RSM_ARTICULATION_STATE

/* ARTICULATION DEVICE STATE: ROBOTIC ARM */

GROUP                             = ARM_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "ARM"
  ARTICULATION_DEVICE_NAME        = "SAMPLE ARM"
  ARTICULATION_DEVICE_ANGLE       = (1.57291 <rad>,-0.286141 <rad>,
                                     -2.81942 <rad>,3.11076 <rad>,
                                     4.86046 <rad>,1.57228 <rad>,
                                     -0.285633 <rad>,-2.82144 <rad>,
                                     3.11019 <rad>,4.86115 <rad>,
                                     0.0602422 <rad>)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("JOINT 1 AZIMUTH-HALL SENSOR",
                                     "JOINT 2 ELEVATION-HALL SENSOR",
                                     "JOINT 3 ELBOW-HALL SENSOR",
                                     "JOINT 4 WRIST-HALL SENSOR",
                                     "JOINT 5 TURRET-HALL SENSOR",
                                     "JOINT 1 AZIMUTH-RESOLVER",
                                     "JOINT 2 ELEVATION-RESOLVER",
                                     "JOINT 3 ELBOW-RESOLVER",
                                     "JOINT 4 WRIST-RESOLVER",
                                     "JOINT 5 TURRET-RESOLVER",
                                     "SCS DOCKING CLOCK ANGLE")
  ARTICULATION_DEVICE_TEMP        = (-19.7273 <degC>,-23.5292 <degC>,
                                     -17.4182 <degC>,-21.0148 <degC>,
                                     -23.7649 <degC>,0.0 <degC>,
                                     -39.6613 <degC>)
  ARTICULATION_DEVICE_TEMP_NAME   = ("AZIMUTH JOINT","ELEVATION JOINT",
                                     "ELBOW JOINT","WRIST JOINT",
                                     "TURRET JOINT",
                                     "DEFLECTION BODY DELTA TEMPERATURE",
                                     "DEFLECTION ARM DELTA TEMPERATURE")
  ARTICULATION_DEV_INSTRUMENT_ID  = "PIXL"
  ARTICULATION_DEV_VECTOR         = (-0.114597,-0.0622403,0.99146)
  ARTICULATION_DEV_VECTOR_NAME    = "GRAVITY"
  CONTACT_SENSOR_STATE            = ("NO CONTACT","NO CONTACT","NO CONTACT"
                                     ,"NO CONTACT","NO CONTACT","NO CONTACT"
                                     ,"NO CONTACT","NO CONTACT")
  CONTACT_SENSOR_STATE_NAME       = ("FACILITY CONTACT SENSOR A",
                                     "FACILITY CONTACT SENSOR B",
                                     "DRILL STABILIZER 1",
                                     "DRILL STABILIZER 2","DOCK 1","DOCK 2",
                                     "DOCK 3","DOCK 4")
  ART_DEV_COMPONENT_STATE         = (0,PIXL)
  ART_DEV_COMPONENT_STATE_NAME    = ("PRELOAD_VALUE","PRELOAD_TOOL")
  DEVICE_POSE_QUATERNION          = (0.965268,0.0156119,-0.0634516,0.252957)
  DEVICE_POSE_NAME                = "arm_attitude_reference"
END_GROUP                         = ARM_ARTICULATION_STATE

/* ARTICULATION DEVICE STATE: MOBILITY CHASSIS */

GROUP                             = CHASSIS_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "CHASSIS"
  ARTICULATION_DEVICE_NAME        = "MOBILITY CHASSIS"
  ARTICULATION_DEVICE_ANGLE       = (-0.0,-0.0,-0.000213053,4.26106e-05,
                                     0.0850929,-0.0434146,0.0203608,
                                     -0.00506445,0.0,0.0,0.0,0.0,0.0,0.0)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("LEFT FRONT WHEEL STEER MOTOR",
                                     "RIGHT FRONT WHEEL STEER MOTOR",
                                     "LEFT REAR WHEEL STEER MOTOR",
                                     "RIGHT REAR WHEEL STEER MOTOR",
                                     "LEFT BOGIE","RIGHT BOGIE",
                                     "LEFT DIFFERENTIAL",
                                     "RIGHT DIFFERENTIAL",
                                     "LEFT FRONT WHEEL DRIVE MOTOR",
                                     "RIGHT FRONT WHEEL DRIVE MOTOR",
                                     "LEFT MIDDLE WHEEL DRIVE MOTOR",
                                     "RIGHT MIDDLE WHEEL DRIVE MOTOR",
                                     "LEFT REAR WHEEL DRIVE MOTOR",
                                     "RIGHT REAR WHEEL DRIVE MOTOR")
  ARTICULATION_DEVICE_MODE        = DEPLOYED
  ARTICULATION_DEV_VECTOR         = (0.483887,-0.00488281,3.68701)
  ARTICULATION_DEV_VECTOR_NAME    = "GRAVITY"
END_GROUP                         = CHASSIS_ARTICULATION_STATE

/* ARTICULATION DEVICE STATE: HIGH GAIN ANTENNA */

GROUP                             = HGA_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "HGA"
  ARTICULATION_DEVICE_NAME        = "HIGH GAIN ANTENNA"
  ARTICULATION_DEVICE_ANGLE       = (1.13443 <rad>,-0.784997 <rad>)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("AZIMUTH","ELEVATION")
  ARTICULATION_DEVICE_MODE        = DEPLOYED
END_GROUP                         = HGA_ARTICULATION_STATE

/* OBSERVATION REQUEST */

GROUP                             = OBSERVATION_REQUEST_PARMS
  COMMAND_INSTRUMENT_ID           = "MCAMZ_BOTH"
  AUTO_EXPOSURE_DATA_CUT          = 150
  AUTO_EXPOSURE_PERCENT           = 10.0
  AUTO_EXPOSURE_PIXEL_FRACTION    = 2.0
  DETECTOR_ERASE_COUNT            = 2047
  EXPOSURE_TYPE                   = MANUAL
  EXPOSURE_DURATION_COUNT         = 3
  FILTER_NAME                     = "ZCAM_L0_RGB"
  FILTER_NUMBER                   = 0
  INSTRUMENT_COORDINATE           = (-0.0902,-0.0064)
  INSTRUMENT_COORDINATE_NAME      = ("AZIMUTH_RELATIVE","ELEVATION_RELATIVE")
  INSTRUMENT_COORD_FRAME_ID       = "LL"
  INSTRUMENT_COORD_FRAME_INDEX    = 0
  MAX_AUTO_EXPOS_ITERATION_COUNT  = 8
  INSTRUMENT_COORDINATE_TYPE      = AZEL_REL
  INSTRUMENT_FOCUS_MODE           = PREVIOUS
  INSTRUMENT_FOCUS_DISTANCE       = 0 <mm>
  INSTRUMENT_MODE_ID              = "MODE_0X0009 20 MHz"
END_GROUP                         = OBSERVATION_REQUEST_PARMS

/* IMAGE REQUEST */

GROUP                             = IMAGE_REQUEST_PARMS
  DOWNLOAD_PRIORITY               = 88
  PIXEL_DOWNSAMPLE_OPTION         = NONE
  SAMPLE_BIT_MODE_ID              = "MCZ_LUT0"
  INST_CMPRS_MODE                 = 0
  IMAGE_ID                        = "1008758005"
  INST_CMPRS_DEFERRED_FLAG        = "TRUE"
  INST_CMPRS_NAME                 = "MSSS_LOSSLESS"
  INSTRUMENT_FOCUS_POSITION_CNT   = 0
  INSTRUMENT_FOCUS_STEPS          = 0
  INSTRUMENT_FOCUS_STEP_SIZE      = 0
  INSTRUMENT_ZOOM_POSITION_CNT    = 9600
  COMMANDED_FOCAL_LENGTH          = 110.0 <mm>
END_GROUP                         = IMAGE_REQUEST_PARMS

/* SUBFRAME REQUEST */

GROUP                             = SUBFRAME_REQUEST_PARMS
  SUBFRAME_TYPE                   = NONE
  FIRST_LINE                      = 1
  FIRST_LINE_SAMPLE               = 1
  LINES                           = 1200
  LINE_SAMPLES                    = 1648
END_GROUP                         = SUBFRAME_REQUEST_PARMS

/* THUMBNAIL REQUEST */

GROUP                             = THUMBNAIL_REQUEST_PARMS
  DOWNLOAD_PRIORITY               = 28
END_GROUP                         = THUMBNAIL_REQUEST_PARMS

/* INSTRUMENT STATE RESULTS */

GROUP                             = INSTRUMENT_STATE_PARMS
  AZIMUTH_FOV                     = 6.35693 <deg>
  ELEVATION_FOV                   = 4.63392 <deg>
  BAYER_METHOD                    = RAW_BAYER
  CFA_TYPE                        = BAYER_RGGB
  CFA_VENUE                       = NONE
  DETECTOR_FIRST_LINE             = 1
  DETECTOR_FIRST_LINE_SAMPLE      = 1
  DETECTOR_LINES                  = 1200
  DETECTOR_LINE_SAMPLES           = 1648
  DOWNSAMPLE_METHOD               = NONE
  EXPOSURE_COUNT                  = 184
  EXPOSURE_DURATION               = 18.4 <ms>
  FILTER_NAME                     = "ZCAM_L0_RGB"
  FILTER_NUMBER                   = 0
  FOCUS_POSITION_COUNT            = 3174
  INSTRUMENT_TEMPERATURE          = (33.3791,-14.4039,-19.8979,-17.834)
  INSTRUMENT_TEMPERATURE_NAME     = ("DEA","HEAD_FPA","HEAD_HTR_1",
                                     "HEAD_HTR_2")
  INSTRUMENT_TEMPERATURE_STATUS   = (0,0,0,0)
  PIXEL_AVERAGING_HEIGHT          = 1
  PIXEL_AVERAGING_WIDTH           = 1
  SAMPLE_BIT_MODE_ID              = "MCZ_LUT0"
  DEVICE_COMPONENT_STATE          = (1,0)
  DEVICE_COMPONENT_STATE_NAME     = ("DEA POWER","HEATER POWER")
  FILTER_POSITION_COUNT           = 0
  ZOOM_POSITION_COUNT             = 9600
  FOCAL_LENGTH                    = 110.0 <mm>
  DC_OFFSET                       = 110
  CENTER_FILTER_WAVELENGTH        = (630 <nm>,544 <nm>,480 <nm>)
  SAMPLE_BIT_METHOD               = HARDWARE_INVERTED
END_GROUP                         = INSTRUMENT_STATE_PARMS

/* COMPRESSION RESULTS */

GROUP                             = COMPRESSION_PARMS
  INST_CMPRS_MODE                 = 0
  INST_CMPRS_NAME                 = "MSSS_LOSSLESS"
  INST_CMPRS_QUALITY              = 0
  INST_CMPRS_RATIO                = 0.0
  INST_CMPRS_DEFERRED_FLAG        = "FALSE"
END_GROUP                         = COMPRESSION_PARMS

/* DERIVED GEOMETRY DATA ELEMENTS: ROVER FRAME */

GROUP                             = ROVER_DERIVED_GEOMETRY_PARMS
  REFERENCE_COORD_SYSTEM_INDEX    = (37,1798,10,0,0,0,40,0,0,0)
  REFERENCE_COORD_SYSTEM_NAME     = "ROVER_NAV_FRAME"
  INSTRUMENT_AZIMUTH              = 71.9023 <deg>
  INSTRUMENT_ELEVATION            = 5.04761 <deg>
END_GROUP                         = ROVER_DERIVED_GEOMETRY_PARMS

/* DERIVED GEOMETRY DATA ELEMENTS: SITE FRAME */

GROUP                             = SITE_DERIVED_GEOMETRY_PARMS
  REFERENCE_COORD_SYSTEM_INDEX    = 37
  REFERENCE_COORD_SYSTEM_NAME     = "SITE_FRAME"
  SOLAR_AZIMUTH                   = 279.372 <deg>
  SOLAR_ELEVATION                 = 33.7442 <deg>
  INSTRUMENT_AZIMUTH              = 100.781 <deg>
  INSTRUMENT_ELEVATION            = 2.79378 <deg>
END_GROUP                         = SITE_DERIVED_GEOMETRY_PARMS

/* DERIVED IMAGE DATA ELEMENTS */

GROUP                             = DERIVED_IMAGE_PARMS
  INPUT_PRODUCT_ID                = 
"ZL0_0753_0733800936_770EDR_N0371798ZCAM08758_1100LMJ01"
  INVERSE_LUT_FILE_NAME           = "ilut/M20_MCZ_LUT0.txt"
  DERIVED_IMAGE_TYPE              = IMAGE
  UNITS                           = "W/M**2/SR/NM"
  RADIOMETRIC_CORRECTION_TYPE     = "CORNELLRAD"
  RADIOMETRIC_TYPE                = "Spectral Radiance"
  RADIOMETRIC_COEFF               = (5.50968e-07 <W/M**2/SR/NM / DN/S>,
                                    5.09128e-07 <W/M**2/SR/NM / DN/S>,
                                    5.38216e-07 <W/M**2/SR/NM / DN/S>)
  RADIOMETRIC_COEFF_STD           = (4.83878e-08 <W/M**2/SR/NM / DN/S>,
                                    4.47157e-08 <W/M**2/SR/NM / DN/S>,
                                    4.72732e-08 <W/M**2/SR/NM / DN/S>)
  RESPONSIVITY_R                  = 0.208936 <e-/ph>
  RESPONSIVITY_G                  = 0.249976 <e-/ph>
  RESPONSIVITY_B                  = 0.28495 <e-/ph>
  EFFECTIVE_WAVELENGTH            = (629 <nm>,543 <nm>,480 <nm>)
  FSUN                            = (6.09988e+20 <W/M**2/SR/NM>,
                                    5.92132e+20 <W/M**2/SR/NM>,
                                    5.38135e+20 <W/M**2/SR/NM>)
  HOT_PIXEL_COUNT                 = 0
  HOT_PIXEL_THRESH_FACTOR         = 3
  SATURATED_PIXEL_COUNT           = 0
  SATURATED_PIXEL_THRESH          = 2000 <DN>
  SATURATED_THRESH                = 
(0.056594 <W/M**2/SR/NM>,0.052296 <W/M**2/SR/NM>, 0.055284 <W/M**2/SR/NM>)
  NONLINEAR_PIXEL_COUNT           = 0
  NONLINEAR_PIXEL_THRESH          = 1500 <DN above bias>
  NONLINEAR_THRESH                = 
(0.044916 <W/M**2/SR/NM>,0.041505 <W/M**2/SR/NM>, 0.043876<W/M**2/SR/NM>)
  NOSIGNAL_PIXEL_COUNT            = 0
  BIAS_COEFFS_FILE_NAME           = "SIMULATED V2.0"
  DYNAMIC_BIAS_FILE_NAME          = "L0_bias_dyn.tif"
  STATIC_BIAS_FILE_NAME           = "L7_bias.tif"
  CONTINUOUS_FLAT2_FILE_NAME      = "L0_9600_poor_v3.tif"
  CONTINUOUS_FLAT1_FILE_NAME      = "L0_8652_poor_v3.tif"
  SKY_FLAT_FIELD_FILE_NAME        = "SKY_TN17L0_9600_v3.tif"
  FLAT_FIELD_FILE_NAME            = "TAMBL0_8652_v1.tif"
  BAD_PIXEL_FILE_NAME             = "L_Bad_Pixels.tif"
  FLAT_FIELD_FILE_DESC            = ("Mastcam-Z radiometric pre-flight flat
                                     field for L0 at zoom 8652 Prepared by 
                                    A. Hayes.",
                                     "Mastcam-Z continuous pre-flight flat 
                                    field for L0 at zoom 0 Prepared by A.Ha
                                    yes.",
                                     "Mastcam-Z continuous pre-flight flat 
                                    field for L0 at zoom 9600 Prepared by A
                                    .Hayes.",
                                     "Mastcam-Z static bias file for L Prep
                                    ared by A.Hayes.",
                                     "Mastcam-Z dynamnic bias file for L0 P
                                    repared by A.Hayes.",
                                     "Mastcam-Z sky flat field for L0 at zo
                                    om 9600 Prepared by A.Hayes.")
  RADIANCE_SCALING_FACTOR         = 1.339256528e-06 <W/M**2/NM/SR>
  RADIANCE_OFFSET                 = 0.002009721939 <W/M**2/NM/SR>
END_GROUP                         = DERIVED_IMAGE_PARMS

/* MINI_HEADER DATA ELEMENTS */

GROUP                             = MINI_HEADER
  IMAGE_ID                        = "510"
  MAGIC_NUMBERS                   = (FF00F0CA,1010CC28)
  SPACECRAFT_CLOCK_START_COUNT    = "733800944.601"
  DETECTOR_ERASE_COUNT            = 2047
  INSTRUMENT_MODE_ID              = "MODE_0X0009 20 MHz"
  FILTER_NUMBER                   = 0
  EXPOSURE_DURATION_COUNT         = 184
  FIRST_LINE_SAMPLE               = 1
  FIRST_LINE                      = 1
  LINE_SAMPLES                    = 1648
  LINES                           = 1200
  INSTRUMENT_FOCUS_MODE           = PREVIOUS
  INSTRUMENT_FOCUS_POSITION       = 0
  INSTRUMENT_FOCUS_STEP_SIZE      = 0
  INSTRUMENT_FOCUS_STEPS          = 0
  AUTO_FOCUS_ZSTACK_FLAG          = "0"
  AUTO_EXPOSURE_DATA_CUT          = 150
  AUTO_EXPOSURE_PIXEL_FRACTION    = 2
  AUTO_EXPOSURE_PERCENT           = 10
  MAX_AUTO_EXPOS_ITERATION_COUNT  = 8
  INST_CMPRS_MODE                 = 0
  INST_CMPRS_NAME                 = "NONE"
  INST_CMPRS_QUALITY              = 0
  SAMPLE_BIT_MODE_ID              = "MCZ_LUT0"
  INSTRUMENT_STATE                = (FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
                                     TRUE,TRUE)
  INSTRUMENT_STATE_NAME           = ("SPARE","UV_LED","VIS1_LED","VIS2_LED"
                                     ,"SPARE","FILTER_HALL_STATE",
                                     "COVER_HALL_STATE","FOCUS_HALL_STATE")
  INSTRUMENT_SERIAL_NUMBER        = "4007"
  ARTICULATION_DEV_POSITION       = (3174,0,9600)
  ARTICULATION_DEV_POSITION_NAME  = ("FOCUS","FILTER","ZOOM")
  DC_OFFSET                       = 110
  INITIAL_SIZE                    = 1977664
  INSTRUMENT_MODE                 = (0,0,0,0,0,0,1,0,0,1)
  INSTRUMENT_MODE_NAME            = ("SPARE","CCD_STATE","LED1_CONTROL",
                                     "LED2_CONTROL","LED3_CONTROL",
                                     "VIDEO_EXPOSURE","CLKDIV2",
                                     "LONG_INTEGRATION_MODE","TEST_MODE",
                                     "CLKDIV1")
END_GROUP                         = MINI_HEADER

/* IMAGE DATA ELEMENTS */

OBJECT                            = IMAGE
  INTERCHANGE_FORMAT              = BINARY
  LINES                           = 1200
  LINE_SAMPLES                    = 1648
  SAMPLE_TYPE                     = MSB_INTEGER
  SAMPLE_BITS                     = 16
  BANDS                           = 1
  BAND_STORAGE_TYPE               = BAND_SEQUENTIAL
  FIRST_LINE                      = 1
  FIRST_LINE_SAMPLE               = 1
  INVALID_CONSTANT                = 0.0
  MISSING_CONSTANT                = 0.0
  SAMPLE_BIT_MASK                 = 2#0000111111111111#
  SCALING_FACTOR                  = 1.339256528e-06
  OFFSET                          = 0.002009721939
END_OBJECT                        = IMAGE

/* DRILL ARTICULATION STATE */

GROUP                             = DRILL_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "DRILL"
  ARTICULATION_DEVICE_NAME        = "DRILL"
  ARTICULATION_DEVICE_ANGLE       = (-0.58365 <rad>,-0.467855 <rad>,
                                     0.0 <rad>)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("SPINDLE OUTPUT POSITION-RESOLVER",
                                     "CHUCK POSITION-RESOLVER",
                                     "PERCUSS POSITION-RESOLVER")
  ARTICULATION_DEVICE_MODE        = DRILL
END_GROUP                         = DRILL_ARTICULATION_STATE

/* SCS ARTICULATION STATE */

GROUP                             = SCS_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "SCS"
  ARTICULATION_DEVICE_NAME        = "SAMPLE CACHE SYSTEM"
  ARTICULATION_DEVICE_ANGLE       = (256.215 <rad>,249.932 <rad>)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("SCS BIT CAROUSEL-HALL SENSOR",
                                     "SCS BIT CAROUSEL-RESOLVER")
  ARTICULATION_DEVICE_MODE        = "SEAL ACTIVATED"
END_GROUP                         = SCS_ARTICULATION_STATE

/* SHA ARTICULATION STATE */

GROUP                             = SHA_ARTICULATION_STATE
  ARTICULATION_DEVICE_ID          = "SHA"
  ARTICULATION_DEVICE_NAME        = "SAMPLE HANDLING ARM"
  ARTICULATION_DEVICE_ANGLE       = (0.0179931 <rad>,-0.239406 <rad>,
                                     2.68496 <rad>,0.0 <rad>,-0.239482 <rad>
                                     ,2.68443 <rad>)
  ARTICULATION_DEVICE_ANGLE_NAME  = ("SHA JOINT 1 Z-HALL SENSOR",
                                     "SHA JOINT 2 SHOULDER-HALL SENSOR",
                                     "SHA JOINT 3 ELBOW-HALL SENSOR",
                                     "SHA JOINT 1 Z-RESOLVER",
                                     "SHA JOINT 2 SHOULDER-RESOLVER",
                                     "SHA JOINT 3 ELBOW-RESOLVER")
END_GROUP                         = SHA_ARTICULATION_STATE

/* IMAGE HEADER DATA ELEMENTS */

OBJECT                            = IMAGE_HEADER
 HEADER_TYPE                      = VICAR2
 INTERCHANGE_FORMAT               = ASCII
 BYTES                            = 16480
 ^DESCRIPTION                     = "VICAR2.TXT"
END_OBJECT                        = IMAGE_HEADER
END

When trying to access values with units and exponents like pdr.metadata['DERIVED_IMAGE_PARMS']['RADIANCE_SCALING_FACTOR'] pdr outputs the following: {'value': 1.339256528, 'units': 'W/M**2/NM/SR'}`

PDR omits the exponent, the correct value from the label is RADIANCE_SCALING_FACTOR = 1.339256528e-06 <W/M**2/NM/SR>

I didn't see the problem with unitless values like pdr.metadata['IMAGE']['SCALING_FACTOR']

m-stclair commented 9 months ago

Thank you for the bug report. Funny to us because we work with this dataset constantly, but apparently never cared about the values with units.

Fixed in 67088ce1801d5d16290350973c179336bd2a0886.

This fix will be included in the next pdr release, which will likely be within the next few weeks. If you need access to this fix urgently, please install from source and use the develop branch.

m-stclair commented 9 months ago

closed by https://github.com/MillionConcepts/pdr/commit/67088ce1801d5d16290350973c179336bd2a0886.

michaelaye commented 9 months ago

Aren't you using PVL for reading PDS3 labels? If not, why not? I'm afraid we might run into problems there in the future, because many people do use it, and now it could be that pdr provides one value and pvl another one. Note that I don't know if pvl reads this correctly or not, I'm just worried that there exist two different readers for it now apparently, and I do know that MASA pays attention to pvl because officials asked the plpy team what its maintenance status is.

m-stclair commented 9 months ago

No. Although we offer hooks for parsing labels with pvl, pvl is not part of pdr's metadata-reading workflow. This is basically because pvl has fundamentally different goals. It prioritizes reading PVL labels completely and comprehensively, in order to provide formally correct Python representations of every type of PVL object and feature. pdr, by contrast, primarily wants to ingest the metadata it needs to correctly interpret observational data, and to do so in a rapid, fault-tolerant way.

We originally did use pvl. However, we want pdr to be usable in performance-sensitive pipelines that need to deal with large numbers of products.

We removed pvl from pdr's workflows because its completeness presented serious performance concerns, to the point that we would otherwise have become unable to use pdr in our own performance-sensitive applications as they scaled (our signal use case was, ironically, ZCAM data processing).

pdr's current PDS3 label parser is roughly 2 orders of magnitude faster than pvl for most products -- an even larger relative difference on longer labels. We think that most planetary processing pipelines care more about things like quickly figuring out how to read array data than things like automatically interpreting all the datetimes in a label. In metadata-only applications -- say, summary statistics on a large archive -- this can be the difference between minutes or days for gathering the specific metadata values you need.

This is not to say that there are no applications that might care about automatically interpreting all the datetimes in a label, and pvl is very good at that kind of thing, which is why we retain a hook for it.

Another way to put this might be that we do not really think of the pdr.Metadata object as the full and complete representation of the label, but rather a distillation of and interface to its semantic content. The LABEL object is the representation of the label. You should not have to load the LABEL as a complete object to read the ARRAY any more than you should have to load the ARRAY to read the LABEL.

sschmaus commented 9 months ago

Thanks for the quick fix!