Пример #1
0
def get_exec_args(workflow: LinearWorkflow, eopatch_list: List[str], config: PostProcessConfig) -> List[dict]:
    """ Utility function to get execution arguments """
    exec_args = []
    tasks = workflow.get_tasks()

    load_bbox = LoadTask(path=f's3://{config.bucket_name}/{config.eopatches_folder}', features=[FeatureType.BBOX])

    for name in tqdm(eopatch_list):
        single_exec_dict = {}

        try:
            eop = load_bbox.execute(eopatch_folder=name)

            for task_name, task in tasks.items():
                if isinstance(task, ExportToTiff):
                    single_exec_dict[task] = dict(filename=f'{name}-{eop.bbox.crs.epsg}.tiff')

                if isinstance(task, (LoadTask, SaveTask)):
                    single_exec_dict[task] = dict(eopatch_folder=name)

            exec_args.append(single_exec_dict)

        except ResourceNotFound as exc:
            print(f'{name} - {exc}')

    return exec_args
Пример #2
0
def test_nonexistent_location(fs_loader):
    path = "./folder/subfolder/new-eopatch/"
    empty_eop = EOPatch()

    with fs_loader() as temp_fs:
        with pytest.raises(ResourceNotFound):
            EOPatch.load(path, filesystem=temp_fs)

        empty_eop.save(path, filesystem=temp_fs)

    with TempFS() as temp_fs:
        full_path = os.path.join(temp_fs.root_path, path)
        with pytest.raises(CreateFailed):
            EOPatch.load(full_path)

        load_task = LoadTask(full_path)
        with pytest.raises(CreateFailed):
            load_task.execute()

        empty_eop.save(full_path)
        assert os.path.exists(full_path)

    with TempFS() as temp_fs:
        full_path = os.path.join(temp_fs.root_path, path)
        save_task = SaveTask(full_path)
        save_task.execute(empty_eop)
        assert os.path.exists(full_path)
Пример #3
0
    def test_nonexistent_location(self):
        path = './folder/subfolder/new-eopatch/'
        empty_eop = EOPatch()

        for fs_loader in self.filesystem_loaders:
            with fs_loader() as temp_fs:
                with self.assertRaises(ResourceNotFound):
                    EOPatch.load(path, filesystem=temp_fs)

                empty_eop.save(path, filesystem=temp_fs)

        with TempFS() as temp_fs:
            full_path = os.path.join(temp_fs.root_path, path)
            with self.assertRaises(CreateFailed):
                EOPatch.load(full_path)

            load_task = LoadTask(full_path)
            with self.assertRaises(CreateFailed):
                load_task.execute()

            empty_eop.save(full_path)
            self.assertTrue(os.path.exists(full_path))

        with TempFS() as temp_fs:
            full_path = os.path.join(temp_fs.root_path, path)
            save_task = SaveTask(full_path)
            save_task.execute(empty_eop)
            self.assertTrue(os.path.exists(full_path))
 def tasks(self, bands_task=LoadTask(".")):
     input_task = LoadTask(".")
     return [
         (input_task, [bands_task], f"Calculate index {self.input_feature[1]}"),
         (self.basic_statistic, [input_task], f"Basic statistics {self.input_feature[1]}"),
         (self.rolling_windows, [input_task], f"Rolling window statistics {self.input_feature[1]}"),
         (self.max_mean_len_task, [self.rolling_windows], f"Max mean len statistic {self.input_feature[1]}"),
         (self.positive_derivative_task, [input_task], f"Positive derivative statistics {self.input_feature[1]}"),
         (self.negative_derivative_task, [input_task], f"Negative derivative statistics {self.input_feature[1]}"),
     ]
 def to_workflow(self):
     input_task = LoadTask(".")  # Dummy to show correct graph
     return EOWorkflow([
         (input_task, [], "Download bands"),
         *self.tasks(input_task),
     ]
     )
Пример #6
0
def predict_using_model(patch_dir, model_file, method, window_size):
    ''' Defines a workflow that will perform the prediction step on a given EOPatch.

        For a given EOPatch, use the specified model to apply prediction step.
        
        Parameters:
            
            - patch_dir: the directory that contains the patch
            - model_file; the path to the model file.
            - method: The local noramalization method, one of 'min', 'median' or 'mean'. This should be the same as the one used to train the model. 
            - window_size: The window_size used in the local normalization step. Should be the same as that used to train the model. 
            
       
        Returns:
            Nothing. Updates the EOPatch on disk.
    '''

    path = patch_dir
    if (type(path) != str):
        path = str(path)
    save = SaveTask(path=path,
                    overwrite_permission=OverwritePermission.OVERWRITE_PATCH)
    load_task = LoadTask(path=path)
    local_norm = LocalNormalization()

    detect_plastics = DetectPlastics(model_file=model_file)
    workflow = LinearWorkflow(load_task, local_norm, detect_plastics, save)
    workflow.execute(
        {local_norm: {
            'method': method,
            'window_size': window_size
        }})
Пример #7
0
def get_gsaa_to_eopatch_workflow(config: GsaaToEopatchConfig) -> EOWorkflow:
    # set up AWS credentials
    sh_config = set_sh_config(config)

    # load patch
    load_task = LoadTask(path=f's3://{config.bucket_name}/{config.eopatches_folder}', config=sh_config)
    # add original vectors to patch
    vec2vec = DB2Vector(database=config.database,
                        user=config.user, password=config.password,
                        host=config.host, port=config.port, crs=config.crs,
                        vector_output_feature=config.vector_feature)
    # get extent mask from vector
    vec2ras = VectorToRaster(config.vector_feature,
                             config.extent_feature,
                             values=1, raster_shape=(config.width, config.height),
                             no_data_value=config.no_data_value,
                             buffer=config.buffer_poly, write_to_existing=False)
    # get boundary mask from extent mask
    ras2bound = Extent2Boundary(config.extent_feature,
                                config.boundary_feature,
                                structure=disk(config.disk_radius))
    # get distance from extent mask
    ras2dist = Extent2Distance(config.extent_feature,
                               config.distance_feature,
                               normalize=True)
    # save new features
    save_task = SaveTask(path=f's3://{config.bucket_name}/{config.eopatches_folder}',
                         features=[config.vector_feature,
                                   config.extent_feature,
                                   config.boundary_feature,
                                   config.distance_feature],
                         overwrite_permission=OverwritePermission.OVERWRITE_FEATURES, config=sh_config)

    return LinearWorkflow(load_task, vec2vec, vec2ras, ras2bound, ras2dist, save_task)
Пример #8
0
def plot_classifications(patchDir, features=None):
    ''' Method that will take a given patch plot the results of the model for that patch.
    
        Parameters:
            - patchDir: the directory of the EOPatch to visualize
            - features: Features, could be the training dataset, to overlay on the scatter plots.

        Returns
            Nothing. Will create a file called classifications.png in the EOPatch folder.
    '''
    patch = LoadTask(path=str(patchDir)).execute()
    classifcations = patch.data['CLASSIFICATION'][0, :, :, 0]
    ndvi = patch.data['NDVI'][0, :, :, 0]
    fdi = patch.data['FDI'][0, :, :, 0]
    norm_ndvi = patch.data['NORM_NDVI'][0, :, :, 0]
    norm_fdi = patch.data['NORM_FDI'][0, :, :, 0]

    fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(20, 30))
    axs = axs.flatten()

    fndvi = norm_ndvi.flatten()
    ffdi = norm_fdi.flatten()
    fclassifications = classifcations.flatten()
    fclassifications[(ffdi < 0.007)] = 0

    p_grid = np.array([cols_rgb[val] for val in fclassifications])

    axs[0].set_title("Labels")
    axs[0].imshow(
        p_grid.reshape(classifcations.shape[0], classifcations.shape[1], 3))

    axs[1].imshow(patch.data['NDVI'][0, :, :, 0])
    axs[1].set_title('NDVI')
    axs[2].imshow(patch.data['FDI'][0, :, :, 0])
    axs[2].set_title('FDI')

    for cat in colors.keys():
        mask = classifcations == cat
        axs[3].scatter(norm_ndvi[mask].flatten(),
                       norm_fdi[mask].flatten(),
                       c=colors[cat],
                       s=0.5,
                       alpha=0.2)
        if (features):
            features.plot.scatter(
                x='normed_ndvi',
                y='normed_fdi',
                ax=axs[3],
                color=features.label.apply(lambda l: colors[catMap[l]]))

    axs[4].imshow(norm_ndvi)
    axs[4].set_title('Normed NDVI')

    axs[5].imshow(norm_fdi)
    axs[5].set_title('Normed FDI')

    plt.tight_layout()
    plt.savefig(Path(patchDir) / 'classifications.png')
    plt.close(fig)
Пример #9
0
def get_post_processing_workflow(config: PostProcessConfig) -> LinearWorkflow:
    sh_config = set_sh_config(config)

    load_task = LoadTask(path=f's3://{config.bucket_name}/{config.eopatches_folder}',
                         features=[config.feature_extent,
                                   config.feature_boundary,
                                   (FeatureType.MASK, 'CLM'),
                                   (FeatureType.MASK, 'IS_DATA'),
                                   FeatureType.TIMESTAMP,
                                   FeatureType.META_INFO,
                                   FeatureType.BBOX],
                         config=sh_config), 'Load EOPatch'

    merge_extent_tasks = [(TemporalMerging(feature=config.feature_extent,
                                           feature_merged=(FeatureType.DATA_TIMELESS,
                                                           f'{config.feature_extent[1]}_{month}'),
                                           woy_start=woy_start, woy_end=woy_end,
                                           percentile=config.percentile,
                                           max_cloud_coverage=config.max_cloud_coverage), f'Merge EXTENT for {month}')
                          for month, (woy_start, woy_end) in config.time_intervals.items()]

    merge_boundary_tasks = [(TemporalMerging(feature=config.feature_boundary,
                                             feature_merged=(FeatureType.DATA_TIMELESS,
                                                             f'{config.feature_boundary[1]}_{month}'),
                                             woy_start=woy_start, woy_end=woy_end,
                                             percentile=config.percentile,
                                             max_cloud_coverage=config.max_cloud_coverage),
                             f'Merge BOUNDARY for {month}')
                            for month, (woy_start, woy_end) in config.time_intervals.items()]

    combine_tasks = [(CombineUpsample(
        feature_extent=(FeatureType.DATA_TIMELESS, f'{config.feature_extent[1]}_{month}'),
        feature_boundary=(FeatureType.DATA_TIMELESS, f'{config.feature_boundary[1]}_{month}'),
        feature_output=(FeatureType.DATA_TIMELESS, f'PREDICTED_{config.model_version}_{month}'),
        scale_factor=config.scale_factor, disk_size=config.disk_size), f'Combine masks for {month}')
        for month in config.time_intervals]

    save_task = SaveTask(path=f's3://{config.bucket_name}/{config.eopatches_folder}',
                         features=[(FeatureType.DATA_TIMELESS, f'{config.feature_extent[1]}_{month}')
                                   for month in config.time_intervals] +
                                  [(FeatureType.DATA_TIMELESS, f'{config.feature_boundary[1]}_{month}')
                                   for month in config.time_intervals] +
                                  [(FeatureType.DATA_TIMELESS, f'PREDICTED_{config.model_version}_{month}')
                                   for month in config.time_intervals],
                         overwrite_permission=OverwritePermission.OVERWRITE_FEATURES,
                         config=sh_config), 'Save Task'

    export_tasks = [(ExportToTiff(feature=(FeatureType.DATA_TIMELESS, f'PREDICTED_{config.model_version}_{month}'),
                                  folder=f's3://{config.bucket_name}/{config.tiffs_folder}/{month}/',
                                  image_dtype=np.float32), f'Export tiffs for {month}')
                    for month in config.time_intervals]

    workflow = LinearWorkflow(load_task, *merge_extent_tasks, *merge_boundary_tasks,
                              *combine_tasks, save_task, *export_tasks)

    return workflow
Пример #10
0
def test_output_task_in_workflow(test_eopatch_path, test_eopatch):
    load = EONode(LoadTask(test_eopatch_path))
    output = EONode(OutputTask(name="result-name"), inputs=[load])

    workflow = EOWorkflow([load, output, EONode(DummyTask(), inputs=[load])])

    results = workflow.execute()

    assert len(results.outputs) == 1
    assert results.outputs["result-name"] == test_eopatch
Пример #11
0
def extract_targets(patchDir):
    path = patchDir
    if (type(path) != str):
        path = str(path)

    patch = LoadTask(path=path).execute()
    box = patch.bbox

    classification = patch.data['CLASSIFICATION'][0, :, :, 0]
    print(classification)
    for coord in np.argwhere(classification == catMap['Debris']):
        print(coord)
Пример #12
0
def test_save_and_load_tasks(eopatch, fs_loader):
    folder = "foo-folder"
    patch_folder = "patch-folder"
    with fs_loader() as temp_fs:
        temp_fs.makedir(folder)

        save_task = SaveTask(folder, filesystem=temp_fs, compress_level=9)
        load_task = LoadTask(folder, filesystem=temp_fs, lazy_loading=False)

        saved_eop = save_task(eopatch, eopatch_folder=patch_folder)
        bbox_path = fs.path.join(folder, patch_folder, "bbox.geojson.gz")
        assert temp_fs.exists(bbox_path)
        assert saved_eop == eopatch

        eop = load_task(eopatch_folder=patch_folder)
        assert eop == eopatch
Пример #13
0
    def test_save_and_load_tasks(self):
        folder = 'foo-folder'
        patch_folder = 'patch-folder'
        for fs_loader in self.filesystem_loaders:
            with fs_loader() as temp_fs:
                temp_fs.makedir(folder)

                save_task = SaveTask(folder,
                                     filesystem=temp_fs,
                                     compress_level=9)
                load_task = LoadTask(folder,
                                     filesystem=temp_fs,
                                     lazy_loading=False)

                saved_eop = save_task(self.eopatch,
                                      eopatch_folder=patch_folder)
                bbox_path = fs.path.join(folder, patch_folder, 'bbox.pkl.gz')
                self.assertTrue(temp_fs.exists(bbox_path))
                self.assertEqual(saved_eop, self.eopatch)

                eop = load_task(eopatch_folder=patch_folder)
                self.assertEqual(eop, self.eopatch)
Пример #14
0
def load_and_apply_local_norm(feature_index,method, window_size):

    '''A function to apply the local normalization step to each feature
        
                Parameters:
                        feature (GeoSeries): A row from the GeoDataFrame produced by load_fetures_from_file
                        feature_index (int): The integer used in saving the EOPatch to disk.
                        method: One of 'min', 'median' or 'mean' indicating the type of averaging the window function should use.
                        window_size: The extent in pixles that averaging should carried out over. 

                Returns:
                       EOPatch including the normalized data
    '''
    load_task = LoadTask(path=f'data/Training/feature_{feature_index}/')
    local_norm = LocalNormalization()
    
    workflow = LinearWorkflow(load_task, local_norm)
    patch = workflow.execute({
        local_norm: {
            'method' : method,
            'window_size': window_size
        }
    })
    return patch
Пример #15
0
    def execute(self, eopatch):
        elevation = eopatch[self.feature[0]][self.feature[1]].squeeze()
        gradient = ndimage.gaussian_gradient_magnitude(elevation, 1)
        eopatch.add_feature(self.result_feature[0], self.result_feature[1],
                            gradient[..., np.newaxis])

        return eopatch


if __name__ == '__main__':
    # path = 'E:/Data/PerceptiveSentinel'
    path = '/home/beno/Documents/test/Slovenia/'
    size_small = (337, 333)
    size_big = (505, 500)

    load = LoadTask(path, lazy_loading=True)
    save_path_location = path
    if not os.path.isdir(save_path_location):
        os.makedirs(save_path_location)
    save = SaveTask(save_path_location,
                    overwrite_permission=OverwritePermission.OVERWRITE_PATCH)

    dem = SentinelHubDemTask((FeatureType.DATA_TIMELESS, 'DEM'), size=size_big)
    grad = AddGradientTask((FeatureType.DATA_TIMELESS, 'DEM'),
                           (FeatureType.DATA_TIMELESS, 'INCLINATION'))

    workflow = LinearWorkflow(load, dem, grad, save)

    no_patches = 1061

    execution_args = []
Пример #16
0
    path = 'E:/Data/PerceptiveSentinel'
    # path = '/home/beno/Documents/test'
    gdf, bbox_list = generate_slo_shapefile(path)

    broken_patches = [12]
    download_patches(path, gdf, bbox_list, broken_patches)

    # no_patches = 1085
    no_patches = 1061


    # path = '/home/beno/Documents/test'
    # path = 'E:/Data/PerceptiveSentinel'

    patch_location = path + '/Slovenia/'
    load = LoadTask(patch_location, lazy_loading=True)

    save_path_location = path + '/Slovenia/'
    if not os.path.isdir(save_path_location):
        os.makedirs(save_path_location)

    save = SaveTask(save_path_location, overwrite_permission=OverwritePermission.OVERWRITE_PATCH)

    addStreamNDVI = AddStreamTemporalFeaturesTask(data_feature='NDVI')
    addStreamSAVI = AddStreamTemporalFeaturesTask(data_feature='SAVI')
    addStreamEVI = AddStreamTemporalFeaturesTask(data_feature='EVI')
    addStreamARVI = AddStreamTemporalFeaturesTask(data_feature='ARVI')
    addStreamSIPI = AddStreamTemporalFeaturesTask(data_feature='SIPI')
    addStreamNDWI = AddStreamTemporalFeaturesTask(data_feature='NDWI')

    # add_data = S2L1CWCSInput(
Пример #17
0
def run_prediction_on_eopatch(
        eopatch_name: str,
        config: PredictionConfig,
        model: ResUnetA = None,
        normalisation_factors: pd.DataFrame = None) -> dict:
    """ Run prediction workflow on one eopatch. Model and dataframe can be provided to avoid loading them every time """
    sh_config = set_sh_config(config)

    filesystem = prepare_filesystem(config)

    if normalisation_factors is None:
        normalisation_factors = load_metadata(filesystem, config)

    if model is None:
        model = load_model(filesystem, config)

    load_task = LoadTask(
        path=f's3://{config.bucket_name}/{config.eopatches_folder}',
        features=[
            config.feature_bands, config.reference_distance,
            config.reference_extent, config.reference_boundary,
            FeatureType.TIMESTAMP, FeatureType.META_INFO, FeatureType.BBOX
        ],
        config=sh_config)

    save_task = SaveTask(
        path=f's3://{config.bucket_name}/{config.eopatches_folder}',
        features=[
            config.feature_extent, config.feature_boundary,
            config.feature_distance, FeatureType.META_INFO
        ],
        overwrite_permission=OverwritePermission.OVERWRITE_FEATURES,
        config=sh_config)

    try:
        eop = load_task.execute(eopatch_folder=eopatch_name)

        eop = prediction_fn(eop,
                            normalisation_factors=normalisation_factors,
                            normalise=config.normalise,
                            model=model,
                            model_name=config.model_name,
                            extent_feature=config.feature_extent,
                            boundary_feature=config.feature_boundary,
                            distance_feature=config.feature_distance,
                            suffix=config.model_version,
                            batch_size=config.batch_size,
                            n_classes=config.n_classes,
                            bands_feature=config.feature_bands,
                            reference_boundary=config.reference_boundary,
                            reference_distance=config.reference_distance,
                            reference_extent=config.reference_extent)

        _ = save_task.execute(eop, eopatch_folder=eopatch_name)

        del eop

        return dict(name=eopatch_name, status='Success')

    except Exception as exc:
        return dict(name=eopatch_name, status=exc)