Пример #1
0
    def _create_gridded_product(self,
                                product_name,
                                grid_data,
                                base_product=None,
                                **kwargs):
        from polar2grid.core.containers import GriddedProduct
        if base_product is None:
            base_product = kwargs
        else:
            base_product = base_product.copy(as_dict=True)
            base_product.update(kwargs)
        base_product["product_name"] = product_name
        base_product["grid_data"] = grid_data

        if base_product.get("grid_definition") is None:
            msg = "No grid definition provided to base composite on (use `base_product` or `grid_definition`)"
            LOG.error(msg)
            raise ValueError(msg)

        return GriddedProduct(**base_product)
Пример #2
0
    def _remap_scene_nearest(self,
                             swath_scene,
                             grid_def,
                             share_dynamic_grids=True,
                             share_remap_mask=True,
                             **kwargs):
        # TODO: Make methods more flexible than just a function call
        gridded_scene = GriddedScene()
        grid_name = grid_def["grid_name"]

        # Group products together that shared the same geolocation
        product_groups = defaultdict(list)
        for product_name, swath_product in swath_scene.items():
            swath_def = swath_product["swath_definition"]
            geo_id = swath_def["swath_name"]
            product_groups[geo_id].append(product_name)

        grid_coverage = kwargs.get("grid_coverage", GRID_COVERAGE)
        orig_grid_def = grid_def
        for geo_id, product_names in product_groups.items():
            pp_names = "\n\t".join(product_names)
            LOG.debug(
                "Running ll2cr on the geolocation data for the following products:\n\t%s",
                pp_names)
            LOG.debug("Swath name: %s", geo_id)

            # TODO: Move into it's own function if this gets complicated
            # TODO: Add some multiprocessing
            try:
                swath_def = swath_scene[product_names[0]]["swath_definition"]
                if not share_dynamic_grids:
                    grid_def = orig_grid_def.copy()
                cols_fn, rows_fn = self.run_ll2cr(swath_def, grid_def)
            except StandardError:
                LOG.error("Remapping error")
                if self.exit_on_error:
                    raise
                continue

            LOG.debug(
                "Running nearest neighbor for the following products:\n\t%s",
                "\n\t".join(product_names))
            edge_res = swath_def.get("limb_resolution", None)
            if kwargs.get("distance_upper_bound", None) is None:
                if edge_res is not None:
                    if grid_def.is_latlong:
                        distance_upper_bound = (edge_res /
                                                2) / grid_def.cell_width_meters
                    else:
                        distance_upper_bound = (edge_res /
                                                2) / grid_def["cell_width"]
                    LOG.debug("Distance upper bound dynamically set to %f",
                              distance_upper_bound)
                else:
                    distance_upper_bound = 3.0
                kwargs["distance_upper_bound"] = distance_upper_bound

            try:
                grid_x, grid_y = numpy.mgrid[:grid_def["height"], :
                                             grid_def["width"]]
                # we need flattened versions of these
                shape = (swath_def["swath_rows"] *
                         swath_def["swath_columns"], )
                cols_array = numpy.memmap(cols_fn,
                                          shape=shape,
                                          dtype=swath_def["data_type"])
                rows_array = numpy.memmap(rows_fn,
                                          shape=shape,
                                          dtype=swath_def["data_type"])
                good_mask = ~mask_helper(cols_array, swath_def["fill_value"])
                if share_remap_mask:
                    for product_name in product_names:
                        LOG.debug(
                            "Combining data masks before building KDTree for nearest neighbor: %s",
                            product_name)
                        good_mask &= ~swath_scene[product_name].get_data_mask(
                        ).ravel()
                x = _ndim_coords_from_arrays(
                    (cols_array[good_mask], rows_array[good_mask]))
                xi = _ndim_coords_from_arrays((grid_y, grid_x))
                dist, i = cKDTree(x).query(
                    xi, distance_upper_bound=kwargs["distance_upper_bound"])
            except StandardError:
                LOG.debug("Remapping exception: ", exc_info=True)
                LOG.error("Remapping error")
                if self.exit_on_error:
                    self._clear_ll2cr_cache()
                    raise
                continue

            product_filepaths = swath_scene.get_data_filepaths(product_names)
            output_filepaths = self._add_prefix("grid_%s_" % (grid_name, ),
                                                *product_filepaths)

            # Prepare the products
            fill_value = numpy.nan
            for product_name, output_fn in izip(product_names,
                                                output_filepaths):
                LOG.debug(
                    "Running nearest neighbor on '%s' with search distance %f",
                    product_name, kwargs["distance_upper_bound"])
                if os.path.isfile(output_fn):
                    if not self.overwrite_existing:
                        LOG.error(
                            "Intermediate remapping file already exists: %s" %
                            (output_fn, ))
                        raise RuntimeError(
                            "Intermediate remapping file already exists: %s" %
                            (output_fn, ))
                    else:
                        LOG.warning(
                            "Intermediate remapping file already exists, will overwrite: %s",
                            output_fn)

                try:
                    image_array = swath_scene[product_name].get_data_array(
                    ).ravel()
                    values = numpy.append(image_array[good_mask],
                                          image_array.dtype.type(fill_value))
                    output_array = values[i]
                    output_array.tofile(output_fn)

                    # Give the gridded product ownership of the remapped data
                    swath_product = swath_scene[product_name]
                    gridded_product = GriddedProduct()
                    gridded_product.from_swath_product(swath_product)
                    gridded_product["grid_definition"] = grid_def
                    gridded_product["fill_value"] = fill_value
                    gridded_product["grid_data"] = output_fn

                    # Check grid coverage
                    valid_points = numpy.count_nonzero(
                        ~gridded_product.get_data_mask())
                    grid_covered_ratio = valid_points / float(
                        grid_def["width"] * grid_def["height"])
                    grid_covered = grid_covered_ratio > grid_coverage
                    if not grid_covered:
                        msg = "Nearest neighbor resampling only found %f%% of the grid covered (need %f%%) for %s" % (
                            grid_covered_ratio * 100, grid_coverage * 100,
                            product_name)
                        LOG.warning(msg)
                        continue
                    LOG.debug(
                        "Nearest neighbor resampling found %f%% of the grid covered for %s"
                        % (grid_covered_ratio * 100, product_name))

                    gridded_scene[product_name] = gridded_product

                    # hopefully force garbage collection
                    del output_array
                except StandardError:
                    LOG.debug("Remapping exception: ", exc_info=True)
                    LOG.error("Remapping error")
                    self._safe_remove(output_fn)
                    if self.exit_on_error:
                        self._clear_ll2cr_cache()
                        raise
                    continue

                LOG.debug("Done running nearest neighbor on '%s'",
                          product_name)

        # Remove ll2cr files now that we are done with them
        self._clear_ll2cr_cache()

        if not gridded_scene:
            raise RuntimeError(
                "Nearest neighbor resampling could not remap any of the data to grid '%s'"
                % (grid_name, ))

        return gridded_scene
Пример #3
0
    def _remap_scene_nearest(self, swath_scene, grid_def, share_dynamic_grids=True, share_remap_mask=True, **kwargs):
        # TODO: Make methods more flexible than just a function call
        gridded_scene = GriddedScene()
        grid_name = grid_def["grid_name"]

        # Group products together that shared the same geolocation
        product_groups = defaultdict(list)
        for product_name, swath_product in swath_scene.items():
            swath_def = swath_product["swath_definition"]
            geo_id = swath_def["swath_name"]
            product_groups[geo_id].append(product_name)

        grid_coverage = kwargs.get("grid_coverage", GRID_COVERAGE)
        orig_grid_def = grid_def
        for geo_id, product_names in product_groups.items():
            pp_names = "\n\t".join(product_names)
            LOG.debug("Running ll2cr on the geolocation data for the following products:\n\t%s", pp_names)
            LOG.debug("Swath name: %s", geo_id)

            # TODO: Move into it's own function if this gets complicated
            # TODO: Add some multiprocessing
            try:
                swath_def = swath_scene[product_names[0]]["swath_definition"]
                if not share_dynamic_grids:
                    grid_def = orig_grid_def.copy()
                cols_fn, rows_fn = self.run_ll2cr(swath_def, grid_def)
            except StandardError:
                LOG.error("Remapping error")
                if self.exit_on_error:
                    raise
                continue

            LOG.debug("Running nearest neighbor for the following products:\n\t%s", "\n\t".join(product_names))
            edge_res = swath_def.get("limb_resolution", None)
            if kwargs.get("distance_upper_bound", None) is None:
                if edge_res is not None:
                    if grid_def.is_latlong:
                        distance_upper_bound = (edge_res / 2) / grid_def.cell_width_meters
                    else:
                        distance_upper_bound = (edge_res / 2) / grid_def["cell_width"]
                    LOG.debug("Distance upper bound dynamically set to %f", distance_upper_bound)
                else:
                    distance_upper_bound = 3.0
                kwargs["distance_upper_bound"] = distance_upper_bound

            try:
                grid_x, grid_y = numpy.mgrid[:grid_def["height"], :grid_def["width"]]
                # we need flattened versions of these
                shape = (swath_def["swath_rows"] * swath_def["swath_columns"],)
                cols_array = numpy.memmap(cols_fn, shape=shape, dtype=swath_def["data_type"])
                rows_array = numpy.memmap(rows_fn, shape=shape, dtype=swath_def["data_type"])
                good_mask = ~mask_helper(cols_array, swath_def["fill_value"])
                if share_remap_mask:
                    for product_name in product_names:
                        LOG.debug("Combining data masks before building KDTree for nearest neighbor: %s", product_name)
                        good_mask &= ~swath_scene[product_name].get_data_mask().ravel()
                x = _ndim_coords_from_arrays((cols_array[good_mask], rows_array[good_mask]))
                xi = _ndim_coords_from_arrays((grid_y, grid_x))
                dist, i = cKDTree(x).query(xi, distance_upper_bound=kwargs["distance_upper_bound"])
            except StandardError:
                LOG.debug("Remapping exception: ", exc_info=True)
                LOG.error("Remapping error")
                if self.exit_on_error:
                    self._clear_ll2cr_cache()
                    raise
                continue

            product_filepaths = swath_scene.get_data_filepaths(product_names)
            output_filepaths = self._add_prefix("grid_%s_" % (grid_name,), *product_filepaths)

            # Prepare the products
            fill_value = numpy.nan
            for product_name, output_fn in izip(product_names, output_filepaths):
                LOG.debug("Running nearest neighbor on '%s' with search distance %f", product_name, kwargs["distance_upper_bound"])
                if os.path.isfile(output_fn):
                    if not self.overwrite_existing:
                        LOG.error("Intermediate remapping file already exists: %s" % (output_fn,))
                        raise RuntimeError("Intermediate remapping file already exists: %s" % (output_fn,))
                    else:
                        LOG.warning("Intermediate remapping file already exists, will overwrite: %s", output_fn)

                try:
                    image_array = swath_scene[product_name].get_data_array().ravel()
                    values = numpy.append(image_array[good_mask], image_array.dtype.type(fill_value))
                    output_array = values[i]
                    output_array.tofile(output_fn)

                    # Give the gridded product ownership of the remapped data
                    swath_product = swath_scene[product_name]
                    gridded_product = GriddedProduct()
                    gridded_product.from_swath_product(swath_product)
                    gridded_product["grid_definition"] = grid_def
                    gridded_product["fill_value"] = fill_value
                    gridded_product["grid_data"] = output_fn

                    # Check grid coverage
                    valid_points = numpy.count_nonzero(~gridded_product.get_data_mask())
                    grid_covered_ratio = valid_points / float(grid_def["width"] * grid_def["height"])
                    grid_covered = grid_covered_ratio > grid_coverage
                    if not grid_covered:
                        msg = "Nearest neighbor resampling only found %f%% of the grid covered (need %f%%) for %s" % (grid_covered_ratio * 100, grid_coverage * 100, product_name)
                        LOG.warning(msg)
                        continue
                    LOG.debug("Nearest neighbor resampling found %f%% of the grid covered for %s" % (grid_covered_ratio * 100, product_name))

                    gridded_scene[product_name] = gridded_product

                    # hopefully force garbage collection
                    del output_array
                except StandardError:
                    LOG.debug("Remapping exception: ", exc_info=True)
                    LOG.error("Remapping error")
                    self._safe_remove(output_fn)
                    if self.exit_on_error:
                        self._clear_ll2cr_cache()
                        raise
                    continue

                LOG.debug("Done running nearest neighbor on '%s'", product_name)

        # Remove ll2cr files now that we are done with them
        self._clear_ll2cr_cache()

        if not gridded_scene:
            raise RuntimeError("Nearest neighbor resampling could not remap any of the data to grid '%s'" % (grid_name,))

        return gridded_scene
Пример #4
0
    def _remap_scene_ewa(self,
                         swath_scene,
                         grid_def,
                         share_dynamic_grids=True,
                         **kwargs):
        # TODO: Make methods more flexible than just a function call
        gridded_scene = GriddedScene()
        grid_name = grid_def["grid_name"]

        # Group products together that shared the same geolocation
        product_groups = defaultdict(list)
        for product_name, swath_product in swath_scene.items():
            swath_def = swath_product["swath_definition"]
            is_cat = swath_product.get('flag_meanings') is not None
            geo_id = swath_def["swath_name"]
            product_groups[(is_cat, geo_id)].append(product_name)

        # keep a copy of the original grid definition
        # if a shared grid definition isn't used then
        # we start from the original
        orig_grid_def = grid_def
        for (is_cat, geo_id), product_names in product_groups.items():
            try:
                LOG.debug(
                    "Running ll2cr on the geolocation data for the following products:\n\t%s",
                    "\n\t".join(sorted(product_names)))
                swath_def = swath_scene[product_names[0]]["swath_definition"]
                if not share_dynamic_grids:
                    grid_def = orig_grid_def.copy()
                cols_fn, rows_fn = self.run_ll2cr(swath_def,
                                                  grid_def,
                                                  swath_usage=kwargs.get(
                                                      "swath_usage",
                                                      SWATH_USAGE))
            except StandardError:
                LOG.error("Remapping error")
                if self.exit_on_error:
                    raise
                continue

            # Run fornav for all of the products at once
            LOG.debug("Running fornav for the following products:\n\t%s",
                      "\n\t".join(sorted(product_names)))
            # XXX: May have to do something smarter if there are float products and integer products together (is_category property on SwathProduct?)
            product_filepaths = list(
                swath_scene.get_data_filepaths(product_names))
            fornav_filepaths = self._add_prefix("grid_%s_" % (grid_name, ),
                                                *product_filepaths)
            for fp in fornav_filepaths:
                if os.path.isfile(fp):
                    if not self.overwrite_existing:
                        LOG.error(
                            "Intermediate remapping file already exists: %s" %
                            (fp, ))
                        raise RuntimeError(
                            "Intermediate remapping file already exists: %s" %
                            (fp, ))
                    else:
                        LOG.warning(
                            "Intermediate remapping file already exists, will overwrite: %s",
                            fp)

            rows_per_scan = swath_def.get("rows_per_scan", 0)
            if rows_per_scan < 2:
                LOG.warning(
                    "Data has less than 2 rows per scan, this is not optimal for the EWA resampling algorithm. All rows will be used as one scan"
                )
                rows_per_scan = swath_def['swath_rows']
            edge_res = swath_def.get("limb_resolution", None)
            fornav_D = kwargs.get("fornav_D", None)
            if fornav_D is None:
                if edge_res is not None:
                    if grid_def.is_latlong:
                        fornav_D = (edge_res / 2) / grid_def.cell_width_meters
                    else:
                        fornav_D = (edge_res / 2) / grid_def["cell_width"]
                    LOG.debug("Fornav 'D' option dynamically set to %f",
                              fornav_D)
                else:
                    fornav_D = 10.0

            mwm = kwargs.get('maximum_weight_mode', False)
            if is_cat and not mwm:
                LOG.debug(
                    "Turning on maximum weight mode in EWA resampling for category products"
                )
                mwm = True

            try:
                # fornav.ms2gt_fornav(
                #     len(product_filepaths),
                #     swath_def["swath_columns"],
                #     swath_def["swath_rows"]/rows_per_scan,
                #     rows_per_scan,
                #     cols_fn,
                #     rows_fn,
                #     product_filepaths,
                #     grid_def["width"],
                #     grid_def["height"],
                #     fornav_filepaths,
                #     swath_data_type_1="f4",
                #     swath_fill_1=swath_scene.get_fill_value(product_names),
                #     grid_fill_1=numpy.nan,
                #     weight_delta_max=fornav_D,
                #     weight_distance_max=kwargs.get("fornav_d", None),
                #     maximum_weight_mode=kwargs.get("maximum_weight_mode", None),
                #     start_scan=(0, 0),
                # )
                cols_array = numpy.memmap(cols_fn,
                                          dtype=numpy.float32,
                                          mode='r',
                                          shape=(swath_def["swath_rows"],
                                                 swath_def["swath_columns"]))
                rows_array = numpy.memmap(rows_fn,
                                          dtype=numpy.float32,
                                          mode='r',
                                          shape=(swath_def["swath_rows"],
                                                 swath_def["swath_columns"]))
                # Assumed that all share the same fill value and data type
                input_dtype = [
                    swath_scene[pn]["data_type"] for pn in product_names
                ]
                input_fill = [
                    swath_scene[pn]["fill_value"] for pn in product_names
                ]
                LOG.debug("Running fornav with D={} and d={}".format(
                    fornav_D, kwargs.get('fornav_d', 1.0)))
                valid_list = fornav.fornav(cols_array,
                                           rows_array,
                                           rows_per_scan,
                                           product_filepaths,
                                           input_dtype=input_dtype,
                                           input_fill=input_fill,
                                           output_arrays=fornav_filepaths,
                                           grid_cols=grid_def["width"],
                                           grid_rows=grid_def["height"],
                                           weight_delta_max=fornav_D,
                                           weight_distance_max=kwargs.get(
                                               "fornav_d", 1.0),
                                           maximum_weight_mode=mwm,
                                           use_group_size=True)
            except StandardError:
                LOG.debug("Remapping exception: ", exc_info=True)
                LOG.error("Remapping error")
                self._safe_remove(*fornav_filepaths)
                if self.exit_on_error:
                    self._clear_ll2cr_cache()
                    raise
                continue

            # Give the gridded product ownership of the remapped data
            for product_name, fornav_fp, valid_points in zip(
                    product_names, fornav_filepaths, valid_list):
                swath_product = swath_scene[product_name]
                gridded_product = GriddedProduct()
                gridded_product.from_swath_product(swath_product)
                gridded_product["grid_definition"] = grid_def
                gridded_product["fill_value"] = numpy.nan
                gridded_product["grid_data"] = fornav_fp

                grid_coverage = kwargs.get("grid_coverage", GRID_COVERAGE)
                grid_covered_ratio = valid_points / float(
                    grid_def["width"] * grid_def["height"])
                grid_covered = grid_covered_ratio > grid_coverage
                if not grid_covered:
                    msg = "EWA resampling only found %f%% of the grid covered (need %f%%) for %s" % (
                        grid_covered_ratio * 100, grid_coverage * 100,
                        product_name)
                    LOG.warning(msg)
                    continue
                LOG.debug(
                    "EWA resampling found %f%% of the grid covered for %s" %
                    (grid_covered_ratio * 100, product_name))
                gridded_scene[product_name] = gridded_product

        self._clear_ll2cr_cache()

        if not gridded_scene:
            self._safe_remove(*fornav_filepaths)
            raise RuntimeError(
                "EWA resampling could not remap any of the data to grid '%s'" %
                (grid_name, ))

        return gridded_scene
Пример #5
0
    def _remap_scene_ewa(self, swath_scene, grid_def, share_dynamic_grids=True, **kwargs):
        # TODO: Make methods more flexible than just a function call
        gridded_scene = GriddedScene()
        grid_name = grid_def["grid_name"]

        # Group products together that shared the same geolocation
        product_groups = defaultdict(list)
        for product_name, swath_product in swath_scene.items():
            swath_def = swath_product["swath_definition"]
            is_cat = swath_product.get('flag_meanings') is not None
            geo_id = swath_def["swath_name"]
            product_groups[(is_cat, geo_id)].append(product_name)

        # keep a copy of the original grid definition
        # if a shared grid definition isn't used then
        # we start from the original
        orig_grid_def = grid_def
        for (is_cat, geo_id), product_names in product_groups.items():
            try:
                LOG.debug("Running ll2cr on the geolocation data for the following products:\n\t%s", "\n\t".join(sorted(product_names)))
                swath_def = swath_scene[product_names[0]]["swath_definition"]
                if not share_dynamic_grids:
                    grid_def = orig_grid_def.copy()
                cols_fn, rows_fn = self.run_ll2cr(swath_def, grid_def,
                                                  swath_usage=kwargs.get("swath_usage", SWATH_USAGE))
            except StandardError:
                LOG.error("Remapping error")
                if self.exit_on_error:
                    raise
                continue

            # Run fornav for all of the products at once
            LOG.debug("Running fornav for the following products:\n\t%s", "\n\t".join(sorted(product_names)))
            # XXX: May have to do something smarter if there are float products and integer products together (is_category property on SwathProduct?)
            product_filepaths = list(swath_scene.get_data_filepaths(product_names))
            fornav_filepaths = self._add_prefix("grid_%s_" % (grid_name,), *product_filepaths)
            for fp in fornav_filepaths:
                if os.path.isfile(fp):
                    if not self.overwrite_existing:
                        LOG.error("Intermediate remapping file already exists: %s" % (fp,))
                        raise RuntimeError("Intermediate remapping file already exists: %s" % (fp,))
                    else:
                        LOG.warning("Intermediate remapping file already exists, will overwrite: %s", fp)

            rows_per_scan = swath_def.get("rows_per_scan", 0)
            if rows_per_scan < 2:
                LOG.warning("Data has less than 2 rows per scan, this is not optimal for the EWA resampling algorithm. All rows will be used as one scan")
                rows_per_scan = swath_def['swath_rows']
            edge_res = swath_def.get("limb_resolution", None)
            fornav_D = kwargs.get("fornav_D", None)
            if fornav_D is None:
                if edge_res is not None:
                    if grid_def.is_latlong:
                        fornav_D = (edge_res / 2) / grid_def.cell_width_meters
                    else:
                        fornav_D = (edge_res / 2) / grid_def["cell_width"]
                    LOG.debug("Fornav 'D' option dynamically set to %f", fornav_D)
                else:
                    fornav_D = 10.0

            mwm = kwargs.get('maximum_weight_mode', False)
            if is_cat and not mwm:
                LOG.debug("Turning on maximum weight mode in EWA resampling for category products")
                mwm = True

            try:
                # fornav.ms2gt_fornav(
                #     len(product_filepaths),
                #     swath_def["swath_columns"],
                #     swath_def["swath_rows"]/rows_per_scan,
                #     rows_per_scan,
                #     cols_fn,
                #     rows_fn,
                #     product_filepaths,
                #     grid_def["width"],
                #     grid_def["height"],
                #     fornav_filepaths,
                #     swath_data_type_1="f4",
                #     swath_fill_1=swath_scene.get_fill_value(product_names),
                #     grid_fill_1=numpy.nan,
                #     weight_delta_max=fornav_D,
                #     weight_distance_max=kwargs.get("fornav_d", None),
                #     maximum_weight_mode=kwargs.get("maximum_weight_mode", None),
                #     start_scan=(0, 0),
                # )
                cols_array = numpy.memmap(cols_fn, dtype=numpy.float32, mode='r', shape=(swath_def["swath_rows"], swath_def["swath_columns"]))
                rows_array = numpy.memmap(rows_fn, dtype=numpy.float32, mode='r', shape=(swath_def["swath_rows"], swath_def["swath_columns"]))
                # Assumed that all share the same fill value and data type
                input_dtype = [swath_scene[pn]["data_type"] for pn in product_names]
                input_fill = [swath_scene[pn]["fill_value"] for pn in product_names]
                LOG.debug("Running fornav with D={} and d={}".format(fornav_D, kwargs.get('fornav_d', 1.0)))
                valid_list = fornav.fornav(cols_array,
                                           rows_array,
                                           rows_per_scan,
                                           product_filepaths,
                                           input_dtype=input_dtype,
                                           input_fill=input_fill,
                                           output_arrays=fornav_filepaths,
                                           grid_cols=grid_def["width"],
                                           grid_rows=grid_def["height"],
                                           weight_delta_max=fornav_D,
                                           weight_distance_max=kwargs.get("fornav_d", 1.0),
                                           maximum_weight_mode=mwm,
                                           use_group_size=True
                                           )
            except StandardError:
                LOG.debug("Remapping exception: ", exc_info=True)
                LOG.error("Remapping error")
                self._safe_remove(*fornav_filepaths)
                if self.exit_on_error:
                    self._clear_ll2cr_cache()
                    raise
                continue

            # Give the gridded product ownership of the remapped data
            for product_name, fornav_fp, valid_points in zip(product_names, fornav_filepaths, valid_list):
                swath_product = swath_scene[product_name]
                gridded_product = GriddedProduct()
                gridded_product.from_swath_product(swath_product)
                gridded_product["grid_definition"] = grid_def
                gridded_product["fill_value"] = numpy.nan
                gridded_product["grid_data"] = fornav_fp

                grid_coverage = kwargs.get("grid_coverage", GRID_COVERAGE)
                grid_covered_ratio = valid_points / float(grid_def["width"] * grid_def["height"])
                grid_covered = grid_covered_ratio > grid_coverage
                if not grid_covered:
                    msg = "EWA resampling only found %f%% of the grid covered (need %f%%) for %s" % (grid_covered_ratio * 100, grid_coverage * 100, product_name)
                    LOG.warning(msg)
                    continue
                LOG.debug("EWA resampling found %f%% of the grid covered for %s" % (grid_covered_ratio * 100, product_name))
                gridded_scene[product_name] = gridded_product

        self._clear_ll2cr_cache()

        if not gridded_scene:
            self._safe_remove(*fornav_filepaths)
            raise RuntimeError("EWA resampling could not remap any of the data to grid '%s'" % (grid_name,))

        return gridded_scene