Пример #1
0
 def test_basic1(self):
     from pyresample.ewa import ll2cr
     from pyresample.geometry import SwathDefinition, AreaDefinition
     from pyresample.utils import proj4_str_to_dict
     lon_arr = create_test_longitude(-95.0,
                                     -75.0, (50, 100),
                                     dtype=np.float64)
     lat_arr = create_test_latitude(18.0, 40.0, (50, 100), dtype=np.float64)
     swath_def = SwathDefinition(lon_arr, lat_arr)
     grid_info = static_lcc.copy()
     cw = grid_info["cell_width"]
     ch = grid_info["cell_height"]
     ox = grid_info["origin_x"]
     oy = grid_info["origin_y"]
     w = grid_info["width"]
     h = grid_info["height"]
     half_w = abs(cw / 2.)
     half_h = abs(ch / 2.)
     extents = [
         ox - half_w, oy - h * abs(ch) - half_h, ox + w * abs(cw) + half_w,
         oy + half_h
     ]
     area = AreaDefinition('test_area', 'test_area', 'test_area',
                           proj4_str_to_dict(grid_info['proj4_definition']),
                           w, h, extents)
     points_in_grid, lon_res, lat_res, = ll2cr(swath_def,
                                               area,
                                               fill=np.nan,
                                               copy=False)
     self.assertEqual(points_in_grid, lon_arr.size,
                      "all points should be contained in a dynamic grid")
     self.assertIs(lon_arr, lon_res)
     self.assertIs(lat_arr, lat_res)
     self.assertEqual(points_in_grid, lon_arr.size,
                      "all these test points should fall in this grid")
Пример #2
0
 def test_basic1(self):
     from pyresample.ewa import ll2cr
     from pyresample.geometry import SwathDefinition, AreaDefinition
     from pyresample.utils import proj4_str_to_dict
     lon_arr = create_test_longitude(-95.0, -75.0, (50, 100), dtype=np.float64)
     lat_arr = create_test_latitude(18.0, 40.0, (50, 100), dtype=np.float64)
     swath_def = SwathDefinition(lon_arr, lat_arr)
     grid_info = static_lcc.copy()
     cw = grid_info["cell_width"]
     ch = grid_info["cell_height"]
     ox = grid_info["origin_x"]
     oy = grid_info["origin_y"]
     w = grid_info["width"]
     h = grid_info["height"]
     half_w = abs(cw / 2.)
     half_h = abs(ch / 2.)
     extents = [
         ox - half_w, oy - h * abs(ch) - half_h,
         ox + w * abs(cw) + half_w, oy + half_h
     ]
     area = AreaDefinition('test_area', 'test_area', 'test_area',
                           proj4_str_to_dict(grid_info['proj4_definition']),
                           w, h, extents)
     points_in_grid, lon_res, lat_res, = ll2cr(swath_def, area,
                                               fill=np.nan, copy=False)
     self.assertEqual(points_in_grid, lon_arr.size, "all points should be contained in a dynamic grid")
     self.assertIs(lon_arr, lon_res)
     self.assertIs(lat_arr, lat_res)
     self.assertEqual(points_in_grid, lon_arr.size, "all these test points should fall in this grid")
Пример #3
0
def _call_ll2cr(lons, lats, target_geo_def):
    """Wrap ll2cr() for handling dask delayed calls better."""
    new_src = SwathDefinition(lons, lats)
    swath_points_in_grid, cols, rows = ll2cr(new_src, target_geo_def)
    if swath_points_in_grid == 0:
        return (lons.shape, np.nan, lons.dtype), (lats.shape, np.nan,
                                                  lats.dtype)
    return np.stack([cols, rows], axis=0)
Пример #4
0
def calc_ewa_params(in_area, out_area):
    """Calculate projection parameters for EWA interpolation"""
    swath_points_in_grid, cols, rows = ll2cr(in_area, out_area)
    del swath_points_in_grid
    cache = {}
    # cache['ewa_swath_points_in_grid'] = \
    #     swath_points_in_grid
    cache['ewa_cols'] = cols
    cache['ewa_rows'] = rows

    return cache
Пример #5
0
def calc_ewa_params(in_area, out_area):
    """Calculate projection parameters for EWA interpolation"""
    swath_points_in_grid, cols, rows = ll2cr(in_area, out_area)
    del swath_points_in_grid
    cache = {}
    # cache['ewa_swath_points_in_grid'] = \
    #     swath_points_in_grid
    cache['ewa_cols'] = cols
    cache['ewa_rows'] = rows

    return cache
Пример #6
0
def _call_ll2cr(lons, lats, target_geo_def, computing_meta=False):
    """Wrap ll2cr() for handling dask delayed calls better."""
    if computing_meta:
        # produce a representative meta array in the best case
        # avoids errors when we return our "empty" tuples below
        return np.zeros((2, *lons.shape), dtype=lons.dtype)
    new_src = SwathDefinition(lons, lats)
    swath_points_in_grid, cols, rows = ll2cr(new_src, target_geo_def)
    if swath_points_in_grid == 0:
        return (lons.shape, np.nan, lons.dtype), (lats.shape, np.nan,
                                                  lats.dtype)
    return np.stack([cols, rows], axis=0)
Пример #7
0
    def _call_ll2cr(self, lons, lats, target_geo_def, swath_usage=0):
        """Wrapper around ll2cr for handling dask delayed calls better."""
        new_src = SwathDefinition(lons, lats)

        swath_points_in_grid, cols, rows = ll2cr(new_src, target_geo_def)
        # FIXME: How do we check swath usage/coverage if we only do this
        #        per-block
        # # Determine if enough of the input swath was used
        # grid_name = getattr(self.target_geo_def, "name", "N/A")
        # fraction_in = swath_points_in_grid / float(lons.size)
        # swath_used = fraction_in > swath_usage
        # if not swath_used:
        #     LOG.info("Data does not fit in grid %s because it only %f%% of "
        #              "the swath is used" %
        #              (grid_name, fraction_in * 100))
        #     raise RuntimeError("Data does not fit in grid %s" % (grid_name,))
        # else:
        #     LOG.debug("Data fits in grid %s and uses %f%% of the swath",
        #               grid_name, fraction_in * 100)

        return np.stack([cols, rows], axis=0)
Пример #8
0
    def _call_ll2cr(self, lons, lats, target_geo_def, swath_usage=0):
        """Wrapper around ll2cr for handling dask delayed calls better."""
        new_src = SwathDefinition(lons, lats)

        swath_points_in_grid, cols, rows = ll2cr(new_src, target_geo_def)
        # FIXME: How do we check swath usage/coverage if we only do this
        #        per-block
        # # Determine if enough of the input swath was used
        # grid_name = getattr(self.target_geo_def, "name", "N/A")
        # fraction_in = swath_points_in_grid / float(lons.size)
        # swath_used = fraction_in > swath_usage
        # if not swath_used:
        #     LOG.info("Data does not fit in grid %s because it only %f%% of "
        #              "the swath is used" %
        #              (grid_name, fraction_in * 100))
        #     raise RuntimeError("Data does not fit in grid %s" % (grid_name,))
        # else:
        #     LOG.debug("Data fits in grid %s and uses %f%% of the swath",
        #               grid_name, fraction_in * 100)

        return np.stack([cols, rows], axis=0)
Пример #9
0
    def __init__(self, in_area, out_area,
                 in_latlons=None, mode=None,
                 radius=10000, nprocs=1):

        if (mode is not None and
                mode not in ["quick", "nearest", "ewa", "bilinear"]):
            raise ValueError("Projector mode must be one of 'nearest', "
                             "'quick', 'ewa', 'bilinear'")

        self.area_file = get_area_file()

        self.in_area = None
        self.out_area = None
        self._cache = None
        self._filename = None
        self.mode = "quick"
        self.radius = radius
        self.conf = ConfigParser.ConfigParser()
        self.conf.read(os.path.join(CONFIG_PATH, "mpop.cfg"))

        # TODO:
        # - Rework so that in_area and out_area can be lonlats.
        # - Add a recompute flag ?

        # Setting up the input area
        try:
            self.in_area = get_area_def(in_area)
            in_id = in_area
        except (utils.AreaNotFound, AttributeError):
            try:
                in_id = in_area.area_id
                self.in_area = in_area
            except AttributeError:
                try:
                    # TODO: Note that latlons are in order (lons, lats)
                    self.in_area = geometry.SwathDefinition(lons=in_latlons[0],
                                                            lats=in_latlons[1])
                    in_id = in_area
                except TypeError:
                    raise utils.AreaNotFound("Input area " +
                                             str(in_area) +
                                             " must be defined in " +
                                             self.area_file +
                                             ", be an area object"
                                             " or longitudes/latitudes must be "
                                             "provided.")

        # Setting up the output area
        try:
            self.out_area = get_area_def(out_area)
            out_id = out_area
        except (utils.AreaNotFound, AttributeError):
            try:
                out_id = out_area.area_id
                self.out_area = out_area
            except AttributeError:
                raise utils.AreaNotFound("Output area " +
                                         str(out_area) +
                                         " must be defined in " +
                                         self.area_file + " or "
                                         "be an area object.")

        # if self.in_area == self.out_area:
        #    return

        # choosing the right mode if necessary
        if mode is None:
            try:
                dicts = in_area.proj_dict, out_area.proj_dict
                del dicts
                self.mode = "quick"
            except AttributeError:
                self.mode = "nearest"
        else:
            self.mode = mode

        filename = (in_id + "2" + out_id + "_" +
                    str(_get_area_hash(self.in_area)) + "to" +
                    str(_get_area_hash(self.out_area)) + "_" +
                    self.mode + ".npz")

        projections_directory = "/var/tmp"
        try:
            projections_directory = self.conf.get("projector",
                                                  "projections_directory")
        except ConfigParser.NoSectionError:
            pass

        self._filename = os.path.join(projections_directory, filename)

        try:
            self._cache = {}
            self._file_cache = np.load(self._filename)
        except:
            logger.info("Computing projection from %s to %s...",
                        in_id, out_id)

            if self.mode == "nearest":
                valid_index, valid_output_index, index_array, distance_array = \
                    kd_tree.get_neighbour_info(self.in_area,
                                               self.out_area,
                                               self.radius,
                                               neighbours=1,
                                               nprocs=nprocs)
                del distance_array
                self._cache = {}
                self._cache['valid_index'] = valid_index
                self._cache['valid_output_index'] = valid_output_index
                self._cache['index_array'] = index_array

            elif self.mode == "quick":
                ridx, cidx = \
                    utils.generate_quick_linesample_arrays(self.in_area,
                                                           self.out_area)
                self._cache = {}
                self._cache['row_idx'] = ridx
                self._cache['col_idx'] = cidx

            elif self.mode == "ewa":
                from pyresample.ewa import ll2cr
                swath_points_in_grid, cols, rows = ll2cr(self.in_area,
                                                         self.out_area)
                self._cache = {}
                # self._cache['ewa_swath_points_in_grid'] = \
                #     swath_points_in_grid
                self._cache['ewa_cols'] = cols
                self._cache['ewa_rows'] = rows

            elif self.mode == "bilinear":

                bilinear_t, bilinear_s, input_idxs, idx_arr = \
                    get_bil_info(self.in_area, self.out_area,
                                 self.radius, neighbours=32,
                                 nprocs=nprocs, masked=False)

                self._cache = {}
                self._cache['bilinear_s'] = bilinear_s
                self._cache['bilinear_t'] = bilinear_t
                self._cache['input_idxs'] = input_idxs
                self._cache['idx_arr'] = idx_arr
Пример #10
0
    def precompute(self, mask=None,
                   # nprocs=1,
                   cache_dir=False,
                   **kwargs):
        """Generate row and column arrays and store it for later use.

        Note: The `mask` keyword should be provided if geolocation may be valid where data points are invalid.
        This defaults to the `mask` attribute of the `data` numpy masked array passed to the `resample` method.
        """

        del kwargs

        source_geo_def = self.source_geo_def

        ewa_hash = self.get_hash(source_geo_def=source_geo_def)

        filename = self._create_cache_filename(cache_dir, ewa_hash)
        self._read_params_from_cache(cache_dir, ewa_hash, filename)

        if self.cache is not None:
            LOG.debug("Loaded ll2cr parameters")
            return self.cache
        else:
            LOG.debug("Computing ll2cr parameters")

        lons, lats = source_geo_def.get_lonlats()
        grid_name = getattr(self.target_geo_def, "name", "N/A")

        # SatPy/PyResample don't support dynamic grids out of the box yet
        is_static = True
        if is_static:
            # we are remapping to a static unchanging grid/area with all of
            # its parameters specified
            # inplace operation so lon_arr and lat_arr are written to
            swath_points_in_grid, cols, rows = ll2cr(source_geo_def,
                                                     self.target_geo_def)
        else:
            raise NotImplementedError(
                "Dynamic ll2cr is not supported by satpy yet")

        # Determine if enough of the input swath was used
        fraction_in = swath_points_in_grid / float(lons.size)
        swath_used = fraction_in > self.swath_usage
        if not swath_used:
            LOG.info("Data does not fit in grid %s because it only %f%% of "
                     "the swath is used" %
                     (grid_name, fraction_in * 100))
            raise RuntimeError("Data does not fit in grid %s" % (grid_name,))
        else:
            LOG.debug("Data fits in grid %s and uses %f%% of the swath",
                      grid_name, fraction_in * 100)

        # Can't save masked arrays to npz, so remove the mask
        if hasattr(rows, 'mask'):
            rows = rows.data
            cols = cols.data

        # it's important here not to modify the existing cache dictionary.
        self.cache = {
            "source_geo_def": source_geo_def,
            "rows": rows,
            "cols": cols,
        }

        self._update_caches(ewa_hash, cache_dir, filename)

        return self.cache
Пример #11
0
    def precompute(self, mask=None,
                   # nprocs=1,
                   cache_dir=False,
                   **kwargs):
        """Generate row and column arrays and store it for later use.

        Note: The `mask` keyword should be provided if geolocation may be valid where data points are invalid.
        This defaults to the `mask` attribute of the `data` numpy masked array passed to the `resample` method.
        """

        del kwargs

        source_geo_def = self.source_geo_def

        kd_hash = self.get_hash(source_geo_def=source_geo_def)
        if isinstance(cache_dir, (str, six.text_type)):
            filename = os.path.join(cache_dir, hashlib.sha1(kd_hash).hexdigest() + ".npz")
        else:
            filename = os.path.join('.', hashlib.sha1(kd_hash.encode("utf-8")).hexdigest() + ".npz")

        try:
            self.cache = self.caches[kd_hash]
            # trick to keep most used caches away from deletion
            del self.caches[kd_hash]
            self.caches[kd_hash] = self.cache

            if cache_dir:
                self.dump(filename)
            return self.cache
        except KeyError:
            if os.path.exists(filename):
                LOG.debug("Loading kd-tree parameters")
                self.cache = dict(np.load(filename))
                self.caches[kd_hash] = self.cache
                while len(self.caches) > CACHE_SIZE:
                    self.caches.popitem(False)
                if cache_dir:
                    self.dump(filename)
                return self.cache
            else:
                LOG.debug("Computing ll2cr parameters")

        lons, lats = source_geo_def.get_lonlats()
        fill_in = np.nan
        grid_name = getattr(self.target_geo_def, "name", "N/A")
        p = self.target_geo_def.proj4_string
        cw = self.target_geo_def.pixel_size_x
        ch = -abs(self.target_geo_def.pixel_size_y)
        w = self.target_geo_def.x_size
        h = self.target_geo_def.y_size
        ox = self.target_geo_def.area_extent[0]
        oy = self.target_geo_def.area_extent[3]

        is_static = True  # SatPy/PyResample don't support dynamic grids out of the box yet
        if is_static:
            # we are remapping to a static unchanging grid/area with all of
            # its parameters specified
            # inplace operation so lon_arr and lat_arr are written to
            swath_points_in_grid = ll2cr(source_geo_def, self.target_geo_def)
        else:
            raise NotImplementedError("Dynamic ll2cr is not supported by satpy yet")
            swath_points_in_grid = ll2cr(source_geo_def, self.target_geo_def)
            swath_points_in_grid, lon_orig, lat_orig, origin_x, origin_y, width, height = results

            # edit the grid information because now we know what it is
            # FIXME: This should be less magical to the user, maybe a separate step for this operation
            self.target_geo_def.origin_x = origin_x
            self.target_geo_def.origin_y = origin_y
            self.target_geo_def.width = width
            self.target_geo_def.height = height

        # Determine if enough of the input swath was used
        fraction_in = swath_points_in_grid / float(lon_arr.size)
        swath_used = fraction_in > self.swath_usage
        if not swath_used:
            LOG.info("Data does not fit in grid %s because it only %f%% of the swath is used" %
                     (grid_name, fraction_in * 100))
            raise RuntimeError("Data does not fit in grid %s" % (grid_name,))
        else:
            LOG.debug("Data fits in grid %s and uses %f%% of the swath", grid_name, fraction_in * 100)

        # it's important here not to modify the existing cache dictionary.
        self.cache = {
            "source_geo_def": source_geo_def,
            "rows": lat_arr,
            "cols": lon_arr,
        }

        self.caches[kd_hash] = self.cache
        while len(self.caches) > CACHE_SIZE:
            self.caches.popitem(False)

        if cache_dir:
            # XXX: Look in to doing memmap-able files instead `arr.tofile(filename)`
            self.dump(filename)
        return self.cache