Commit 246ae894 authored by AustinSanders's avatar AustinSanders Committed by Jesse Mapel
Browse files

Add filter-specific calculations and tests (#450)

* Added filter-specific calculations and tests

* Addressed PR feedback
parent 52ac3906
Loading
Loading
Loading
Loading
+156 −3
Original line number Diff line number Diff line
@@ -892,6 +892,44 @@ class LroLrocWacIsisLabelIsisSpiceDriver(PushFrame, IsisLabel, IsisSpice, Radial
        return 2


    @property
    def filter_number(self):
        """
        Return the filter number from the cub label

        Returns
        -------
        : int
          The filter number
        """
        try:
            return self.label['IsisCube']['BandBin']['FilterNumber'][0]
        except:
            return self.label['IsisCube']['BandBin']['FilterNumber']


    @property
    def fikid(self):
        """
        Naif ID code of the filter dependent instrument codes.

        Expects ikid to be defined. This should be the integer Naif ID code for
        the instrument.

        Returns
        -------
        : int
          Naif ID code used in calculating focal length
        """
        if self.instrument_id == "LRO_LROCWAC_UV":
            base = -85640
        elif self.instrument_id == "LRO_LROCWAC_VIS":
            base = -85630

        fikid = base - self.filter_number
        return fikid


    @property
    def odtk(self):
        """
@@ -902,7 +940,9 @@ class LroLrocWacIsisLabelIsisSpiceDriver(PushFrame, IsisLabel, IsisSpice, Radial
        : list
          Radial distortion coefficients.
        """
        return [self.naif_keywords.get('INS{}_OD_K'.format(self.ikid), None)]
        coeffs = self.naif_keywords.get('INS{}_OD_K'.format(self.fikid), None)
        coeffs = [x * -1 for x in coeffs]
        return coeffs


    @property
@@ -989,6 +1029,12 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial

    @property
    def sensor_name(self):
        """
        Returns
        -------
        : String
          The name of the spacecraft
        """
        return self.label['IsisCube']['Instrument']['SpacecraftName']


@@ -1002,7 +1048,9 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial
        : list
          Radial distortion coefficients.
        """
        return spice.gdpool('INS{}_OD_K'.format(self.ikid), 0, 3).tolist()
        coeffs = spice.gdpool('INS{}_OD_K'.format(self.fikid), 0, 3).tolist()
        coeffs = [x * -1 for x in coeffs]
        return coeffs


    @property
@@ -1028,7 +1076,13 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial

    @property
    def framelets_flipped(self):
        return self.label['IsisCube']['Instrument']['SpacecraftName'] == "Yes"
        """
        Returns
        -------
        : boolean
          True if framelets are flipped, else false
        """
        return self.label['IsisCube']['Instrument']['DataFlipped'] == "Yes"


    @property
@@ -1041,12 +1095,111 @@ class LroLrocWacIsisLabelNaifSpiceDriver(PushFrame, IsisLabel, NaifSpice, Radial

    @property
    def num_frames(self):
        """
        Number of frames in the image

        Returns
        -------
        : int
          Number of frames in the image
        """
        return self.image_lines // (self.framelet_height // self.sampling_factor)


    @property
    def framelet_height(self):
        """
        Return the number of lines in a framelet.

        Returns
        -------
        : int
          The number of lines in a framelet
        """
        if self.instrument_id == "LRO_LROCWAC_UV":
            return 16
        elif self.instrument_id == "LRO_LROCWAC_VIS":
            return 14


    @property
    def filter_number(self):
        """
        Return the filter number from the cub label

        Returns
        -------
        : int
          The filter number
        """
        try:
            return self.label['IsisCube']['BandBin']['FilterNumber'][0]
        except:
            return self.label['IsisCube']['BandBin']['FilterNumber']


    @property
    def fikid(self):
        """
        Naif ID code of the filter dependent instrument codes.

        Expects ikid to be defined. This should be the integer Naif ID code for
        the instrument.

        Returns
        -------
        : int
          Naif ID code used in calculating focal length
        """
        if self.instrument_id == "LRO_LROCWAC_UV":
            base = -85640
        elif self.instrument_id == "LRO_LROCWAC_VIS":
            base = -85630

        fikid = base - self.filter_number
        return fikid


    @property
    def pixel2focal_x(self):
        """
        Expects fikid to be defined. This must be the integer Naif id code of the filter

        Returns
        -------
        : list<double>
        detector to focal plane x
        """
        return list(spice.gdpool('INS{}_TRANSX'.format(self.fikid), 0, 3))


    @property
    def pixel2focal_y(self):
        """
        Expects fikid to be defined. This must be the integer Naif id code of the filter

        Returns
        -------
        : list<double>
        detector to focal plane y
        """
        return list(spice.gdpool('INS{}_TRANSY'.format(self.fikid), 0, 3))


    @property
    def detector_start_line(self):
        """
        Filter-specific starting line

        Returns
        -------
        : int
          Zero based Detector line corresponding to the first image line
        """
        offset = list(spice.gdpool('INS{}_FILTER_OFFSET'.format(self.fikid), 0, 3))
        try:
            # If multiple items are present, use the first one
            offset = offset[0]
        except (IndexError, TypeError):
            pass
        return super().detector_start_line + offset
+34 −28
Original line number Diff line number Diff line
@@ -276,21 +276,17 @@ class test_wac_isis_naif(unittest.TestCase):
        label = get_image_label('wac0000a1c4.uv.even', 'isis3')
        self.driver = LroLrocWacIsisLabelNaifSpiceDriver(label)


    def test_short_mission_name(self):
        assert self.driver.short_mission_name == 'lro'


    def test_intrument_id(self):
        assert self.driver.instrument_id == 'LRO_LROCWAC_UV'


    def test_ephemeris_start_time(self):
        with patch('ale.drivers.lro_drivers.spice.scs2e', return_value=321) as scs2e:
            np.testing.assert_almost_equal(self.driver.ephemeris_start_time, 321)
            scs2e.assert_called_with(-85, '1/274692469:15073')


    def test_detector_center_sample(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
@@ -298,7 +294,6 @@ class test_wac_isis_naif(unittest.TestCase):
            gdpool.assert_called_with('INS-12345_BORESIGHT_SAMPLE', 0, 1)
            bods2c.assert_called_with('LRO_LROCWAC_UV')


    def test_detector_center_line(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
@@ -306,51 +301,53 @@ class test_wac_isis_naif(unittest.TestCase):
            gdpool.assert_called_with('INS-12345_BORESIGHT_LINE', 0, 1)
            bods2c.assert_called_with('LRO_LROCWAC_UV')


    def test_usgscsm_distortion_model(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
            distortion_model = self.driver.usgscsm_distortion_model
            assert distortion_model['radial']['coefficients'] == [1.0]
            gdpool.assert_called_with('INS-12345_OD_K', 0, 3)
            bods2c.assert_called_with('LRO_LROCWAC_UV')


    def test_odtk(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool, \
             patch('ale.drivers.lro_drivers.spice.bods2c', return_value=-12345) as bods2c:
             assert self.driver.odtk == [1.0]
             gdpool.assert_called_with('INS-12345_OD_K', 0, 3)
             bods2c.assert_called_with('LRO_LROCWAC_UV')

        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([1.0])) as gdpool:
             assert self.driver.odtk == [-1.0]
             gdpool.assert_called_with('INS-85641_OD_K', 0, 3)

    def test_light_time_correction(self):
        assert self.driver.light_time_correction == 'LT+S'


    def test_exposure_duration(self):
        np.testing.assert_almost_equal(self.driver.exposure_duration, 0.04)


    def test_sensor_name(self):
        assert self.driver.sensor_name == "LUNAR RECONNAISSANCE ORBITER"


    def test_framelets_flipped(self):
        assert self.driver.framelets_flipped == False


    def test_sampling_factor(self):
        assert self.driver.sampling_factor == 4


    def test_num_frames(self):
        assert self.driver.num_frames == 260


    def test_framelet_height(self):
        assert self.driver.framelet_height == 16

    def test_filter_number(self):
        assert self.driver.filter_number == 1

    def test_fikid(self):
        assert self.driver.fikid == -85641

    def test_pixel2focal_x(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([0, 0, -0.009])) as gdpool:
             assert self.driver.pixel2focal_x == [0, 0, -0.009]
             gdpool.assert_called_with('INS-85641_TRANSX', 0, 3)

    def test_pixel2focal_y(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([0, 0.009, 0])) as gdpool:
             assert self.driver.pixel2focal_y == [0, 0.009, 0]
             gdpool.assert_called_with('INS-85641_TRANSY', 0, 3)

    def test_detector_start_line(self):
        with patch('ale.drivers.lro_drivers.spice.gdpool', return_value=np.array([244])) as gdpool:
             assert self.driver.detector_start_line == 244
             gdpool.assert_called_with('INS-85641_FILTER_OFFSET', 0, 3)

# ========= Test WAC isislabel and isis spice driver =========
class test_wac_isis_isis(unittest.TestCase):

@@ -368,4 +365,13 @@ class test_wac_isis_isis(unittest.TestCase):
        np.testing.assert_almost_equal(self.driver.exposure_duration, 0.04)

    def test_usgscsm_distortion_model(self):
        assert self.driver.usgscsm_distortion_model == {'radial': {'coefficients': [[-0.024, -0.0007]]}}
        assert self.driver.usgscsm_distortion_model == {'radial': {'coefficients': [-0.0258246, -4.66139e-05, -0.000144651]}}

    def test_filter_number(self):
        assert self.driver.filter_number == 1

    def test_fikid(self):
        assert self.driver.fikid == -85641

    def test_odtk(self):
        assert self.driver.odtk == [-0.0258246, -4.66139e-05, -0.000144651]