Commit b2a66d56 authored by Stuart Sides's avatar Stuart Sides Committed by GitHub
Browse files

Updated lro driver and tests to new design (#179)

parent 214fd889
Loading
Loading
Loading
Loading
+126 −85
Original line number Diff line number Diff line
@@ -12,38 +12,36 @@ from ale.base.label_pds3 import Pds3Label
from ale.base.type_sensor import LineScanner


class LroLrocPds3LabelNaifSpiceDriver(Driver, NaifSpice, Pds3Label, LineScanner):
class LroLrocPds3LabelNaifSpiceDriver(NaifSpice, Pds3Label, LineScanner, Driver):
    """
  Driver for reading Lroc NACL, NACR, WAC labels. Requires a Spice mixin to
  acquire addtional ephemeris and instrument data located exclusively in
  spice kernels.
    Driver for reading LROC NACL, NACR (not WAC, it is a push frame) labels. Requires a Spice mixin to
    acquire addtional ephemeris and instrument data located exclusively in SPICE kernels, A PDS3 label,
    and the LineScanner and Driver bases.
    """

    @property
    def instrument_id(self):
        """
    Returns an instrument id for uniquely identifying the instrument, but often
    also used to be piped into Spice Kernels to acquire IKIDs. Therefore they
    are the same ID that spice lib expects as input to bods2c calls.
        The short text name for the instrument

    Ignores Wide Angle for now
        Returns an instrument id uniquely identifying the instrument. Used to acquire
        instrument codes from Spice Lib bods2c routine.

        Returns
        -------
    : str
      instrument id
        str
          The short text name for the instrument
        """

    instrument = self.label.get("INSTRUMENT_ID")
        instrument = super().instrument_id

    # NACL, NACR, or WAC
        frame_id = self.label.get("FRAME_ID")

        if instrument == "LROC" and frame_id == "LEFT":
            return "LRO_LROCNACL"
        elif instrument == "LROC" and frame_id == "RIGHT":
            return "LRO_LROCNACR"
        # WAC not implemented yet


    @property
    def metakernel(self):
@@ -52,7 +50,7 @@ class LroLrocPds3LabelNaifSpiceDriver(Driver, NaifSpice, Pds3Label, LineScanner)

        Returns
        -------
    : string
        : str
          Path to latest metakernel file
        """
        metakernel_dir = config.lro
@@ -69,35 +67,78 @@ class LroLrocPds3LabelNaifSpiceDriver(Driver, NaifSpice, Pds3Label, LineScanner)
    def spacecraft_name(self):
        """
        Spacecraft name used in various SPICE calls to acquire
    ephemeris data.
        ephemeris data. LROC NAC img PDS3 labels do not the have SPACECRAFT_NAME keyword, so we
        override it here to use the label_pds3 property for instrument_host_id

        Returns
        -------
        : str
          Spacecraft name
        """
    return "LRO"
        return self.instrument_host_id

    @property
    def sensor_model_version(self):
        """
        Returns ISIS instrument sensor model version number

        Returns
        -------
        : int
          sensor model version
        """
        return 2

    @property
  def odtk(self):
    def detector_start_sample(self):
        """
        Returns the starting sample contained in the image

        Returns
        -------
    : list
      Radial distortion coefficients
        : int
          Returns the starting sample 
        """
    return spice.gdpool('INS{}_OD_K'.format(self.ikid), 0, 1).tolist()
        return 1

    @property
  def optical_distortion(self):
    def detector_start_line(self):
        """
        Returns the starting line contained in the image

        Returns
        -------
        : int
          Returns the starting line 
        """
        return 1

    @property
    def usgscsm_distortion_model(self):
        """
        The distortion model name with its coefficients

        LRO LROC NAC does not use the default distortion model so we need to overwrite the
        method packing the distortion model into the ISD.

        Returns
        -------
        : dict
          Returns a dict with the model name : dict of the coefficients 
        """
    return {
      "lrolrocnac": {
        "coefficients": self.odtk,
      }
    }

        return {"lrolrocnac":
                {"coefficients": self.odtk}}

    @property
    def odtk(self):
        """
        The coefficients for the distortion model

        Returns
        -------
        : list
          Radial distortion coefficients. There is only one coefficient for LROC NAC l/r
        """
        return spice.gdpool('INS{}_OD_K'.format(self.ikid), 0, 1).tolist()
+48 −106
Original line number Diff line number Diff line
from collections import namedtuple
from unittest import mock

import pytest

# 'Mock' the spice module where it is imported
from conftest import SimpleSpice, get_mockkernels

from collections import namedtuple

import ale
from ale.drivers import lro_drivers
from ale.base import data_naif
from ale.base import label_pds3

from unittest.mock import PropertyMock, patch

from ale.drivers.lro_drivers import LroLrocPds3LabelNaifSpiceDriver
from ale import util

# 'Mock' the spice module where it is imported
from conftest import SimpleSpice, get_mockkernels
from ale.drivers.lro_drivers import LroLrocPds3LabelNaifSpiceDriver


simplespice = SimpleSpice()
data_naif.spice = simplespice
lro_drivers.spice = simplespice
label_pds3.spice = simplespice

LroLrocPds3LabelNaifSpiceDriver.metakernel = get_mockkernels

@pytest.fixture
def lro_lroclabel():
    return """
        PDS_VERSION_ID                     = PDS3

        /*FILE CHARACTERISTICS*/
        RECORD_TYPE                        = FIXED_LENGTH
        RECORD_BYTES                       = 5064
        FILE_RECORDS                       = 13313
        LABEL_RECORDS                      = 1
        ^IMAGE                             = 2

        /*DATA IDENTIFICATION*/
        DATA_SET_ID                        = "LRO-L-LROC-2-EDR-V1.0"
        ORIGINAL_PRODUCT_ID                = nacl0002fc60
        PRODUCT_ID                         = M128963531LE
        MISSION_NAME                       = "LUNAR RECONNAISSANCE ORBITER"
        MISSION_PHASE_NAME                 = "NOMINAL MISSION"
        INSTRUMENT_HOST_NAME               = "LUNAR RECONNAISSANCE ORBITER"
        INSTRUMENT_HOST_ID                 = LRO
        INSTRUMENT_NAME                    = "LUNAR RECONNAISSANCE ORBITER CAMERA"
        INSTRUMENT_ID                      = LROC
        LRO:PREROLL_TIME                   = 2010-05-20T02:57:44.373
        START_TIME                         = 2010-05-20T02:57:44.720
        STOP_TIME                          = 2010-05-20T02:57:49.235
        LRO:SPACECRAFT_CLOCK_PREROLL_COUNT = "1/296017064:22937"
        SPACECRAFT_CLOCK_START_COUNT       = "1/296017064:45694"
        SPACECRAFT_CLOCK_STOP_COUNT        = "1/296017069:13866"
        ORBIT_NUMBER                       = 4138
        PRODUCER_ID                        = LRO_LROC_TEAM
        PRODUCT_CREATION_TIME              = 2013-09-16T19:57:12
        PRODUCER_INSTITUTION_NAME          = "ARIZONA STATE UNIVERSITY"
        PRODUCT_TYPE                       = EDR
        PRODUCT_VERSION_ID                 = "v1.8"
        UPLOAD_ID                          = "SC_2010140_0000_A_V01.txt"

        /*DATA DESCRIPTION*/
        TARGET_NAME                        = "MOON"
        RATIONALE_DESC                     = "TARGET OF OPPORTUNITY"
        FRAME_ID                           = LEFT
        DATA_QUALITY_ID                    = "0"
        DATA_QUALITY_DESC                  = "The DATA_QUALITY_ID is set to an 8-bit
           value that encodes the following data quality information for the
           observation. For each bit  a value of 0 means FALSE and a value of 1 means
           TRUE. More information about the data quality ID can be found in the LROC
           EDR/CDR SIS, section 3.3 'Label and Header Descriptions'.
               Bit 1: Temperature of focal plane array is out of bounds.
               Bit 2: Threshold for saturated pixels is reached.
               Bit 3: Threshold for under-saturated pixels is reached.
               Bit 4: Observation is missing telemetry packets.
               Bit 5: SPICE information is bad or missing.
               Bit 6: Observation or housekeeping information is bad or missing.
               Bit 7: Spare.
               Bit 8: Spare."

        /*ENVIRONMENT*/
        LRO:TEMPERATURE_SCS                = 4.51 <degC>
        LRO:TEMPERATURE_FPA                = 17.88 <degC>
        LRO:TEMPERATURE_FPGA               = -12.33 <degC>
        LRO:TEMPERATURE_TELESCOPE          = 5.91 <degC>
        LRO:TEMPERATURE_SCS_RAW            = 2740
        LRO:TEMPERATURE_FPA_RAW            = 2107
        LRO:TEMPERATURE_FPGA_RAW           = 3418
        LRO:TEMPERATURE_TELESCOPE_RAW      = 2675

        /*IMAGING PARAMETERS*/
        CROSSTRACK_SUMMING                 = 1
        BANDWIDTH                          = 300 <nm>
        CENTER_FILTER_WAVELENGTH           = 600 <nm>
        LINE_EXPOSURE_DURATION             = 0.337600 <ms>
        LRO:LINE_EXPOSURE_CODE             = 0
        LRO:DAC_RESET_LEVEL                = 198
        LRO:CHANNEL_A_OFFSET               = 60
        LRO:CHANNEL_B_OFFSET               = 123
        LRO:COMPAND_CODE                   = 3
        LRO:LINE_CODE                      = 13
        LRO:BTERM                          = (0,16,69,103,128)
        LRO:MTERM                          = (0.5,0.25,0.125,0.0625,0.03125)
        LRO:XTERM                          = (0,64,424,536,800)
        LRO:COMPRESSION_FLAG               = 1
        LRO:MODE                           = 7

        /*DATA OBJECT*/
        OBJECT                             = IMAGE
            LINES                          = 13312
            LINE_SAMPLES                   = 5064
            SAMPLE_BITS                    = 8
            SAMPLE_TYPE                    = LSB_INTEGER
            UNIT                           = "RAW_INSTRUMENT_COUNT"
            MD5_CHECKSUM                   = "0fe91f4b2e93083ee0093e7c8d05f3bc"
        END_OBJECT                         = IMAGE
        END
        """

def test_lro_creation(lro_lroclabel):
    #with LroLrocPds3LabelNaifSpiceDriver(lro_lroclabel) as m:
    #    d = m.to_dict()
    #    assert isinstance(d, dict)

    # Need to insert new tests here, one for each property unique to this driver
    assert True
def driver():
    return LroLrocPds3LabelNaifSpiceDriver("")


@patch('ale.base.label_pds3.Pds3Label.instrument_id', 'LROC')
def test_instrument_id_left(driver):
    with patch.dict(driver.label, {'FRAME_ID':'LEFT'}) as f:
        assert driver.instrument_id == 'LRO_LROCNACL'

@patch('ale.base.label_pds3.Pds3Label.instrument_id', 'LROC')
def test_instrument_id_right(driver):
    with patch.dict(driver.label, {'FRAME_ID':'RIGHT'}) as f:
        assert driver.instrument_id == 'LRO_LROCNACR'

@patch('ale.base.label_pds3.Pds3Label.instrument_host_id', 'LRO')
def test_spacecraft_name(driver):
    assert driver.spacecraft_name == 'LRO'

def test_sensor_model_version(driver):
    assert driver.sensor_model_version == 2

def test_detector_start_sample(driver):
    assert driver.detector_start_sample == 1

def test_detector_start_line(driver):
    assert driver.detector_start_sample == 1

@patch('ale.base.data_naif.NaifSpice.ikid', 123)
def test_odtk(driver):
    assert driver.odtk == [1.0]

@patch('ale.base.data_naif.NaifSpice.ikid', 123)
def test_usgscsm_distortion_model(driver):
    distortion_model = driver.usgscsm_distortion_model
    assert distortion_model['lrolrocnac']['coefficients'] == [1.0]