示例#1
0
    def test_slerp_vec(self):
        lon0 = np.array([[0, 0],
                         [0, 0]])
        lat0 = np.array([[0, 0],
                         [0, 0]])
        lon1 = np.array([[0, 0],
                         [0, 0]])
        lat1 = np.array([[1, 1],
                         [1, 1]])

        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(np.allclose(res[:, :, 0], 0))
        self.assertTrue(np.allclose(res[:, :, 1], 0.5))

        lon0 = np.array([[183, 0],
                         [-90, 0]])
        lat0 = np.array([[0, 89],
                         [89, 89]])
        lon1 = np.array([[179, 180],
                         [90, 180]])
        lat1 = np.array([[0, 89],
                         [89, 87]])

        res = slerp(lon0, lat0, lon1, lat1, 0.5)

        self.assertTrue(np.allclose(res[0, 0, :] % 360, (181, 0)))
        self.assertTrue(np.allclose(res[0, 1, 1], 90))
        self.assertTrue(np.allclose(res[1, 0, 1], 90))
        self.assertTrue(np.allclose(res[1, 1, :], (180, 89)))
示例#2
0
    def test_slerp_pole(self):
        lon0, lat0 = (0, 89)
        lon1, lat1 = (180, 89)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(np.allclose(res[:, :, 1], 90))

        lon0, lat0 = (-90, 89)
        lon1, lat1 = (90, 89)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(np.allclose(res[:, :, 1], 90))

        lon0, lat0 = (0, 89)
        lon1, lat1 = (180, 87)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(np.allclose(res, (180, 89)))
示例#3
0
 def test_slerp_datum(self):
     lon0, lat0 = (183, 0)
     lon1, lat1 = (179, 0)
     res = slerp(lon0, lat0, lon1, lat1, 0.5)
     res %= 360
     self.assertTrue(
         np.allclose(res, (181, 0)))
示例#4
0
    def test_slerp_pole(self):
        lon0, lat0 = (0, 89)
        lon1, lat1 = (180, 89)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(
            np.allclose(res[:, :, 1], 90))

        lon0, lat0 = (-90, 89)
        lon1, lat1 = (90, 89)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(
            np.allclose(res[:, :, 1], 90))

        lon0, lat0 = (0, 89)
        lon1, lat1 = (180, 87)
        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(
            np.allclose(res, (180, 89)))
示例#5
0
    def test_slerp_vec(self):
        lon0 = np.array([[0, 0], [0, 0]])
        lat0 = np.array([[0, 0], [0, 0]])
        lon1 = np.array([[0, 0], [0, 0]])
        lat1 = np.array([[1, 1], [1, 1]])

        res = slerp(lon0, lat0, lon1, lat1, 0.5)
        self.assertTrue(np.allclose(res[:, :, 0], 0))
        self.assertTrue(np.allclose(res[:, :, 1], 0.5))

        lon0 = np.array([[183, 0], [-90, 0]])
        lat0 = np.array([[0, 89], [89, 89]])
        lon1 = np.array([[179, 180], [90, 180]])
        lat1 = np.array([[0, 89], [89, 87]])

        res = slerp(lon0, lat0, lon1, lat1, 0.5)

        self.assertTrue(np.allclose(res[0, 0, :] % 360, (181, 0)))
        self.assertTrue(np.allclose(res[0, 1, 1], 90))
        self.assertTrue(np.allclose(res[1, 0, 1], 90))
        self.assertTrue(np.allclose(res[1, 1, :], (180, 89)))
示例#6
0
    def test_slerp_tvec(self):
        lon0 = np.array([[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                         [0, 0]])
        lat0 = np.array([[0, 0], [5, 0], [10, 0], [15, 0], [20, 0], [25, 0],
                         [30, 0]])
        lon1 = np.array([[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0],
                         [0, 0]])
        lat1 = np.array([[45, 45], [45, 45], [45, 45], [45, 45], [45, 45],
                         [45, 45], [45, 45]])

        t = np.array([[0.5, 0, 0.2, 0.4, 0.6, 0.8, 1]]).T
        t = t[:, :, np.newaxis]
        res = slerp(lon0, lat0, lon1, lat1, t)
        expected = np.array([[22.5, 22.5], [5., 0.], [17., 9.], [27., 18.],
                             [35., 27.], [41., 36.], [45., 45.]])

        self.assertTrue(np.allclose(res[:, :, 0], 0))
        self.assertTrue(np.allclose(res[:, :, 1], expected))
示例#7
0
    def test_slerp_tvec(self):
        lon0 = np.array([[0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0]])
        lat0 = np.array([[0, 0],
                         [5, 0],
                         [10, 0],
                         [15, 0],
                         [20, 0],
                         [25, 0],
                         [30, 0]])
        lon1 = np.array([[0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0],
                         [0, 0]])
        lat1 = np.array([[45, 45],
                         [45, 45],
                         [45, 45],
                         [45, 45],
                         [45, 45],
                         [45, 45],
                         [45, 45]])

        t = np.array([[0.5, 0, 0.2, 0.4, 0.6, 0.8, 1]]).T
        t = t[:, :, np.newaxis]
        res = slerp(lon0, lat0, lon1, lat1, t)
        expected = np.array([[22.5, 22.5],
                             [5., 0.],
                             [17., 9.],
                             [27., 18.],
                             [35., 27.],
                             [41., 36.],
                             [45., 45.]])

        self.assertTrue(np.allclose(res[:, :, 0], 0))
        self.assertTrue(np.allclose(res[:, :, 1], expected))
示例#8
0
    def _adjust_clock_drift(self):
        """Adjust the geolocation to compensate for the clock error."""
        tic = datetime.datetime.now()
        self.get_times()
        try:
            error_utcs, clock_error = get_offsets(self.spacecraft_name)
        except KeyError:
            LOG.info("No clock drift info available for %s",
                     self.spacecraft_name)
            return

        error_utcs = np.array(error_utcs, dtype='datetime64[ms]')
        # interpolate to get the clock offsets at the scan line utcs
        # the clock_error is given in seconds, so offsets are in seconds, too.
        offsets = np.interp(self.utcs.astype(np.uint64),
                            error_utcs.astype(np.uint64),
                            clock_error)
        LOG.info("Adjusting for clock drift of %s to %s seconds.",
                 str(min(offsets)),
                 str(max(offsets)))

        # For the interpolation of geolocations, we need to prepend/append
        # lines. The conversion from offset to line numbers is given by the
        # scan rate = 1/scan frequency.
        scan_rate = datetime.timedelta(milliseconds=1/self.scan_freq)
        offset_lines = offsets / scan_rate.total_seconds()

        # To avoid trouble with missing lines, we will construct an
        # array that covers the whole interpolation range.
        scan_lines = self.scans["scan_line_number"]
        shifted_lines = scan_lines - offset_lines
        shifted_lines_floor = np.floor(shifted_lines).astype(int)
        # compute the line range, note that the max requires a "+1"
        # to cover the interpolation range because of the floor.
        min_line = min(scan_lines.min(), shifted_lines_floor.min())
        max_line = max(scan_lines.max(), shifted_lines_floor.max()+1)
        num_lines = max_line - min_line + 1
        missed_lines = np.setdiff1d(np.arange(min_line, max_line+1), scan_lines)
        missed_utcs = ((missed_lines - scan_lines[0])*np.timedelta64(scan_rate, "ms")
                       + self.utcs[0])
        # calculate the missing geo locations
        missed_lons, missed_lats = self._compute_missing_lonlat(missed_utcs)

        # create arrays of lons and lats for interpolation. The locations
        # correspond to not yet corrected utcs, i.e. the time difference from
        # one line to the other should be equal to the scan rate.
        pixels_per_line = self.lats.shape[1]
        complete_lons = np.full((num_lines, pixels_per_line), np.nan,
                                dtype=np.float)
        complete_lats = np.full((num_lines, pixels_per_line), np.nan,
                                dtype=np.float)

        complete_lons[scan_lines - min_line] = self.lons
        complete_lats[scan_lines - min_line] = self.lats
        complete_lons[missed_lines - min_line] = missed_lons
        complete_lats[missed_lines - min_line] = missed_lats

        # perform the slerp interpolation to the corrected utc times
        slerp_t = shifted_lines - shifted_lines_floor  # in [0, 1)
        slerp_res = slerp(complete_lons[shifted_lines_floor - min_line, :],
                          complete_lats[shifted_lines_floor - min_line, :],
                          complete_lons[shifted_lines_floor - min_line + 1, :],
                          complete_lats[shifted_lines_floor - min_line + 1, :],
                          slerp_t[:, np.newaxis, np.newaxis])

        # set corrected values
        self.lons = slerp_res[:, :, 0]
        self.lats = slerp_res[:, :, 1]
        self.utcs -= (offsets * 1000).astype('timedelta64[ms]')

        toc = datetime.datetime.now()
        LOG.debug("clock drift adjustment took %s", str(toc - tic))
示例#9
0
    def adjust_clock_drift(self):
        """Adjust the geolocation to compensate for the clock error.

        TODO: bad things might happen when scanlines are skipped.
        """
        tic = datetime.datetime.now()
        self.get_times()
        from pygac.clock_offsets_converter import get_offsets
        try:
            offset_times, clock_error = get_offsets(self.spacecraft_name)
        except KeyError:
            LOG.info("No clock drift info available for %s",
                     self.spacecraft_name)
        else:
            offset_times = np.array(offset_times, dtype='datetime64[ms]')
            offsets = np.interp(self.utcs.astype(np.uint64),
                                offset_times.astype(np.uint64), clock_error)
            LOG.info("Adjusting for clock drift of %s to %s",
                     str(min(offsets)), str(max(offsets)))
            self.times = (self.utcs + offsets.astype('timedelta64[s]')).astype(
                datetime.datetime)
            offsets *= -2

            int_offsets = np.floor(offsets).astype(np.int)

            # filling out missing geolocations with computation from pyorbital.
            line_indices = (self.scans["scan_line_number"] + int_offsets)

            missed = sorted((set(line_indices) | set(line_indices + 1)) -
                            set(self.scans["scan_line_number"]))

            min_idx = min(line_indices)
            max_idx = max(max(line_indices),
                          max(self.scans["scan_line_number"] - min_idx)) + 1
            idx_len = max_idx - min_idx + 2

            complete_lons = np.zeros((idx_len, 409), dtype=np.float) * np.nan
            complete_lats = np.zeros((idx_len, 409), dtype=np.float) * np.nan

            complete_lons[self.scans["scan_line_number"] - min_idx] = self.lons
            complete_lats[self.scans["scan_line_number"] - min_idx] = self.lats

            missed_utcs = ((np.array(missed) - 1) * np.timedelta64(500, "ms") +
                           self.utcs[0])

            mlons, mlats = self.compute_lonlat(missed_utcs, True)

            complete_lons[missed - min_idx] = mlons
            complete_lats[missed - min_idx] = mlats

            from pygac.slerp import slerp
            off = offsets - np.floor(offsets)
            res = slerp(complete_lons[line_indices - min_idx, :],
                        complete_lats[line_indices - min_idx, :],
                        complete_lons[line_indices - min_idx + 1, :],
                        complete_lats[line_indices - min_idx + 1, :],
                        off[:, np.newaxis, np.newaxis])

            self.lons = res[:, :, 0]
            self.lats = res[:, :, 1]
            self.utcs += offsets.astype('timedelta64[s]')

        toc = datetime.datetime.now()
        LOG.debug("clock drift adjustment took %s", str(toc - tic))
示例#10
0
 def test_slerp_datum(self):
     lon0, lat0 = (183, 0)
     lon1, lat1 = (179, 0)
     res = slerp(lon0, lat0, lon1, lat1, 0.5)
     res %= 360
     self.assertTrue(np.allclose(res, (181, 0)))
示例#11
0
 def test_slerp(self):
     lon0, lat0 = (0, 0)
     lon1, lat1 = (0, 1)
     self.assertTrue(
         np.allclose(slerp(lon0, lat0, lon1, lat1, 0.5), (0, 0.5)))
示例#12
0
 def test_slerp(self):
     lon0, lat0 = (0, 0)
     lon1, lat1 = (0, 1)
     self.assertTrue(
         np.allclose(slerp(lon0, lat0, lon1, lat1, 0.5), (0, 0.5)))