diff --git a/eis_toolkit/cli.py b/eis_toolkit/cli.py index 3dce7288..347a1666 100644 --- a/eis_toolkit/cli.py +++ b/eis_toolkit/cli.py @@ -6,6 +6,7 @@ import json import os +from contextlib import contextmanager from enum import Enum from itertools import zip_longest from pathlib import Path @@ -15,7 +16,7 @@ import pandas as pd import rasterio import typer -from beartype.typing import List, Optional, Tuple, Union +from beartype.typing import List, Optional, Sequence, Tuple, Union from typing_extensions import Annotated from eis_toolkit.utilities.nodata import nan_to_nodata, nodata_to_nan @@ -415,6 +416,43 @@ class ReplaceCondition(str, Enum): ] +class ProgressLog: # noqa: D101 + @contextmanager + @staticmethod + def reading_input_files(): # noqa: D102 + typer.echo("Opening input files....") + yield + typer.echo("✅ Input files read\n") + + @contextmanager + @staticmethod + def running_algorithm(): # noqa: D102 + typer.echo("Running algorithm...") + yield + typer.echo("✅ Algorithm run succesfully\n") + + @contextmanager + @staticmethod + def saving_output_files(savepath: Union[str, Sequence[str]]): # noqa: D102 + typer.echo("Saving output files...") + yield + if isinstance(savepath, Sequence): + for file in savepath: + typer.echo(f"✅ Output file(s) saved to {file}\n") + else: + typer.echo(f"✅ Output file(s) saved to {savepath}\n") + + @staticmethod + def finish(): # noqa: D102 + typer.echo("✅ Algorithm execution finished succesfully\n") + + +class ResultSender: # noqa: D101 + @staticmethod + def send_dict_as_json(dictionary: dict): # noqa: D102 + typer.echo(f"Results: {json.dumps(dictionary)}") + + def get_enum_values(parameter: Union[Enum, List[Enum]]) -> Union[str, List[str]]: """Get values behind enum parameter definition (required for list enums).""" if isinstance(parameter, List): @@ -431,22 +469,17 @@ def normality_test_raster_cli(input_raster: INPUT_FILE_OPTION, bands: Optional[L """Compute Shapiro-Wilk test for normality on the input raster data.""" from eis_toolkit.exploratory_analyses.normality_test import normality_test_array - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + with rasterio.open(input_raster) as raster: + data = raster.read() + if len(bands) == 0: + bands = None - with rasterio.open(input_raster) as raster: - data = raster.read() - typer.echo("Progress: 25%") - if len(bands) == 0: - bands = None + with ProgressLog.running_algorithm(): results_dict = normality_test_array(data=data, bands=bands, nodata_value=raster.nodata) - typer.echo("Progress: 75%") - - json_str = json.dumps(results_dict) - typer.echo("Progress: 100%") - - typer.echo(f"Results: {json_str}") - typer.echo("Normality test (raster) completed") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # NORMALITY TEST VECTOR @@ -455,20 +488,14 @@ def normality_test_vector_cli(input_vector: INPUT_FILE_OPTION, columns: Optional """Compute Shapiro-Wilk test for normality on the input vector data.""" from eis_toolkit.exploratory_analyses.normality_test import normality_test_dataframe - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") - - results_dict = normality_test_dataframe(data=geodataframe, columns=columns) - - typer.echo("Progress: 75%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - json_str = json.dumps(results_dict) - typer.echo("Progress: 100%") + with ProgressLog.running_algorithm(): + results_dict = normality_test_dataframe(data=geodataframe, columns=columns) - typer.echo(f"Results: {json_str}") - typer.echo("Normality test (vector) completed") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # CHI-SQUARE_TEST @@ -481,20 +508,14 @@ def chi_square_test_cli( """Perform a Chi-square test of independence between a target variable and one or more other variables.""" from eis_toolkit.exploratory_analyses.chi_square_test import chi_square_test - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) # Should we drop geometry columns? - typer.echo("Progress: 25%") - - results_dict = chi_square_test(data=geodataframe, target_column=target_column, columns=columns) - - typer.echo("Progress: 75%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - json_str = json.dumps(results_dict) - typer.echo("Progress: 100%") + with ProgressLog.running_algorithm(): + results_dict = chi_square_test(data=geodataframe, target_column=target_column, columns=columns) - typer.echo(f"Results: {json_str}") - typer.echo("Chi-square test completed") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # CORRELATION MATRIX @@ -509,22 +530,22 @@ def correlation_matrix_cli( """Compute correlation matrix on the input data.""" from eis_toolkit.exploratory_analyses.correlation_matrix import correlation_matrix - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) - geodataframe = gpd.read_file(input_vector) - dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) - typer.echo("Progress: 25%") - - output_df = correlation_matrix( - data=dataframe, columns=columns, correlation_method=get_enum_values(correlation_method), min_periods=min_periods - ) - - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_df = correlation_matrix( + data=dataframe, + columns=columns, + correlation_method=get_enum_values(correlation_method), + min_periods=min_periods, + ) - output_df.to_csv(output_file) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_file): + output_df.to_csv(output_file) - typer.echo("Correlation matrix completed") + ProgressLog.finish() # COVARIANCE MATRIX @@ -539,22 +560,19 @@ def covariance_matrix_cli( """Compute covariance matrix on the input data.""" from eis_toolkit.exploratory_analyses.covariance_matrix import covariance_matrix - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) - output_df = covariance_matrix( - data=dataframe, columns=columns, min_periods=min_periods, delta_degrees_of_freedom=delta_degrees_of_freedom - ) - - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_df = covariance_matrix( + data=dataframe, columns=columns, min_periods=min_periods, delta_degrees_of_freedom=delta_degrees_of_freedom + ) - output_df.to_csv(output_file) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_file): + output_df.to_csv(output_file) - typer.echo("Covariance matrix completed") + ProgressLog.finish() # DBSCAN VECTOR @@ -570,24 +588,22 @@ def dbscan_vector_cli( """Perform DBSCAN clustering on the input vector data.""" from eis_toolkit.exploratory_analyses.dbscan import dbscan_vector - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - output_geodataframe = dbscan_vector( - data=geodataframe, - include_coordinates=include_coordinates, - columns=columns, - max_distance=max_distance, - min_samples=min_samples, - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_geodataframe = dbscan_vector( + data=geodataframe, + include_coordinates=include_coordinates, + columns=columns, + max_distance=max_distance, + min_samples=min_samples, + ) - output_geodataframe.to_file(output_vector, driver="GPKG") - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_vector): + output_geodataframe.to_file(output_vector, driver="GPKG") - typer.echo(f"DBSCAN completed, output vector written to {output_vector}.") + ProgressLog.finish() # DBSCAN RASTER @@ -602,23 +618,21 @@ def dbscan_raster_cli( from eis_toolkit.exploratory_analyses.dbscan import dbscan_array from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - typer.echo("Progress: 25%") - - output_array = dbscan_array(data=stacked_array, max_distance=max_distance, min_samples=min_samples) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_array = dbscan_array(data=stacked_array, max_distance=max_distance, min_samples=min_samples) out_profile = profiles[0] out_profile["nodata"] = -9999 out_profile["count"] = 1 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(output_array, 1) + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(output_array, 1) - typer.echo("Progress: 100%") - typer.echo(f"DBSCAN clustering completed, output raster written to {output_raster}.") + ProgressLog.finish() # K-MEANS CLUSTERING VECTOR @@ -634,24 +648,22 @@ def k_means_clustering_vector_cli( """Perform k-means clustering on the input vector data.""" from eis_toolkit.exploratory_analyses.k_means_cluster import k_means_clustering_vector - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - output_geodataframe = k_means_clustering_vector( - data=geodataframe, - include_coordinates=include_coordinates, - columns=columns, - number_of_clusters=number_of_clusters, - random_state=random_state, - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_geodataframe = k_means_clustering_vector( + data=geodataframe, + include_coordinates=include_coordinates, + columns=columns, + number_of_clusters=number_of_clusters, + random_state=random_state, + ) - output_geodataframe.to_file(output_vector, driver="GPKG") - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_vector): + output_geodataframe.to_file(output_vector, driver="GPKG") - typer.echo(f"K-means clustering completed, output vector written to {output_vector}.") + ProgressLog.finish() # K-MEANS CLUSTERING RASTER @@ -666,25 +678,23 @@ def k_means_clustering_raster_cli( from eis_toolkit.exploratory_analyses.k_means_cluster import k_means_clustering_array from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") - - stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - output_array = k_means_clustering_array( - data=stacked_array, number_of_clusters=number_of_clusters, random_state=random_state - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + output_array = k_means_clustering_array( + data=stacked_array, number_of_clusters=number_of_clusters, random_state=random_state + ) out_profile = profiles[0] out_profile["nodata"] = -9999 out_profile["count"] = 1 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(output_array, 1) + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(output_array, 1) - typer.echo("Progress: 100%") - typer.echo(f"K-means clustering completed, output raster written to {output_raster}.") + ProgressLog.finish() # PARALLEL COORDINATES @@ -704,30 +714,28 @@ def parallel_coordinates_cli( from eis_toolkit.exploratory_analyses.parallel_coordinates import plot_parallel_coordinates - typer.echo("Progress: 10%") - geodataframe = gpd.read_file(input_vector) - dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) - typer.echo("Progress: 25%") - - _ = plot_parallel_coordinates( - dataframe, - color_column_name=color_column_name, - plot_title=plot_title, - palette_name=palette_name, - curved_lines=curved_lines, - ) - typer.echo("Progress: 75%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + dataframe = pd.DataFrame(geodataframe.drop(columns="geometry")) + + with ProgressLog.running_algorithm(): + _ = plot_parallel_coordinates( + dataframe, + color_column_name=color_column_name, + plot_title=plot_title, + palette_name=palette_name, + curved_lines=curved_lines, + ) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("Parallel coordinates plot completed") + ProgressLog.finish() # PCA FOR RASTER DATA @@ -744,14 +752,15 @@ def compute_pca_raster_cli( from eis_toolkit.exploratory_analyses.pca import compute_pca from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - stacked_array, profiles = read_and_stack_rasters(input_rasters, nodata_handling="convert_to_nan") - typer.echo("Progress: 25%") - - transformed_data, principal_components, variances, variance_ratios = compute_pca( - data=stacked_array, number_of_components=number_of_components, nodata_handling=get_enum_values(nodata_handling) - ) + with ProgressLog.running_algorithm(): + transformed_data, principal_components, variances, variance_ratios = compute_pca( + data=stacked_array, + number_of_components=number_of_components, + nodata_handling=get_enum_values(nodata_handling), + ) # Fill np.nan with nodata before writing data to raster transformed_data[transformed_data == np.nan] = -9999 @@ -773,15 +782,13 @@ def compute_pca_raster_cli( "explained_variances": np.round(variances, 4).tolist(), "explained_variance_ratios": np.round(variance_ratios, 4).tolist(), } - json_str = json.dumps(out_dict) - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(transformed_data) + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(transformed_data) - typer.echo("Progress: 100%") - - typer.echo(f"Results: {json_str}") - typer.echo(f"PCA computation (raster) completed, output raster saved to {output_raster}.") + ResultSender.send_dict_as_json(out_dict) + ProgressLog.finish() # PCA FOR VECTOR DATA @@ -798,18 +805,17 @@ def compute_pca_vector_cli( """Compute defined number of principal components for vector data.""" from eis_toolkit.exploratory_analyses.pca import compute_pca - typer.echo("Progress: 10%") - - gdf = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) - transformed_data, principal_components, variances, variance_ratios = compute_pca( - data=gdf, - number_of_components=number_of_components, - columns=columns, - nodata_handling=get_enum_values(nodata_handling), - nodata=nodata, - ) + with ProgressLog.running_algorithm(): + transformed_data, principal_components, variances, variance_ratios = compute_pca( + data=gdf, + number_of_components=number_of_components, + columns=columns, + nodata_handling=get_enum_values(nodata_handling), + nodata=nodata, + ) # Create dictionary from the variance ratios array # variances_ratios_dict = {} @@ -823,13 +829,12 @@ def compute_pca_vector_cli( "explained_variances": np.round(variances, 4).tolist(), "explained_variance_ratios": np.round(variance_ratios, 4).tolist(), } - json_str = json.dumps(out_dict) - transformed_data.to_file(output_vector) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_vector): + transformed_data.to_file(output_vector) - typer.echo(f"Results: {json_str}") - typer.echo(f"PCA computation (vector) completed, output vector saved to {output_vector}.") + ResultSender.send_dict_as_json(out_dict) + ProgressLog.finish() # DESCRIPTIVE STATISTICS (RASTER) @@ -838,17 +843,15 @@ def descriptive_statistics_raster_cli(input_raster: INPUT_FILE_OPTION, band: int """Generate descriptive statistics from raster data.""" from eis_toolkit.exploratory_analyses.descriptive_statistics import descriptive_statistics_raster - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): results_dict = descriptive_statistics_raster(raster, band) - typer.echo("Progress: 75%") + raster.close() - typer.echo("Progress: 100% \n") - - typer.echo(f"Results: {str(results_dict)}") - typer.echo("\nDescriptive statistics (raster) completed") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # DESCRIPTIVE STATISTICS (VECTOR) @@ -857,26 +860,23 @@ def descriptive_statistics_vector_cli(input_file: INPUT_FILE_OPTION, column: str """Generate descriptive statistics from vector or tabular data.""" from eis_toolkit.exploratory_analyses.descriptive_statistics import descriptive_statistics_dataframe - typer.echo("Progress: 10%") - # TODO modify input file detection try: - gdf = gpd.read_file(input_file) - typer.echo("Progress: 25%") - results_dict = descriptive_statistics_dataframe(gdf, column) + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_file) + with ProgressLog.running_algorithm(): + results_dict = descriptive_statistics_dataframe(gdf, column) except: # noqa: E722 try: - df = pd.read_csv(input_file) - typer.echo("Progress: 25%") - results_dict = descriptive_statistics_dataframe(df, column) + with ProgressLog.reading_input_files(): + df = pd.read_csv(input_file) + with ProgressLog.running_algorithm(): + results_dict = descriptive_statistics_dataframe(df, column) except: # noqa: E722 - raise Exception("Could not read input file as raster or dataframe") - typer.echo("Progress: 75%") + raise Exception("Could not read input file as geodataframe") - typer.echo("Progress: 100%") - - typer.echo(f"Results: {str(results_dict)}") - typer.echo("\nDescriptive statistics (vector) completed") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # LOCAL MORAN'S I @@ -892,17 +892,16 @@ def local_morans_i_cli( """Execute Local Moran's I calculation for the data.""" from eis_toolkit.exploratory_analyses.local_morans_i import local_morans_i - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) - gdf = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_gdf = local_morans_i(gdf, column, get_enum_values(weight_type), k, permutations) - out_gdf = local_morans_i(gdf, column, get_enum_values(weight_type), k, permutations) - typer.echo("Progress: 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf.to_file(output_vector) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Local Moran's I completed, output vector saved to {output_vector}.") + ProgressLog.finish() # FEATURE IMPORTANCE @@ -918,25 +917,18 @@ def feature_importance_cli( from eis_toolkit.exploratory_analyses.feature_importance import evaluate_feature_importance from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml - typer.echo("Progress: 10%") - - model = load_model(model_file) - typer.echo("Progress: 20%") + with ProgressLog.reading_input_files(): + model = load_model(model_file) + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + feature_names = [raster.name for raster in input_rasters] - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - typer.echo("Progress: 30%") - - feature_names = [raster.name for raster in input_rasters] - typer.echo("Progress: 40%") - - feature_importance, _ = evaluate_feature_importance(model, X, y, feature_names, n_repeats, random_state) - typer.echo("Progress: 80%") + with ProgressLog.running_algorithm(): + feature_importance, _ = evaluate_feature_importance(model, X, y, feature_names, n_repeats, random_state) results = dict(zip(feature_importance["Feature"], feature_importance["Importance"])) - json_str = json.dumps(results) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + ResultSender.send_dict_as_json(results) + ProgressLog.finish() # --- RASTER PROCESSING --- @@ -954,18 +946,18 @@ def focal_filter_cli( """Apply a basic focal filter to the input raster.""" from eis_toolkit.raster_processing.filters.focal import focal_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = focal_filter(raster=raster, method=method, size=size, shape=get_enum_values(shape)) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Focal filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # GAUSSIAN FILTER @@ -980,18 +972,18 @@ def gaussian_filter_cli( """Apply a gaussian filter to the input raster.""" from eis_toolkit.raster_processing.filters.focal import gaussian_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = gaussian_filter(raster=raster, sigma=sigma, truncate=truncate, size=size) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Gaussial filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # MEXICAN HAT FILTER @@ -1009,20 +1001,20 @@ def mexican_hat_filter_cli( """Apply a mexican hat filter to the input raster.""" from eis_toolkit.raster_processing.filters.focal import mexican_hat_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = mexican_hat_filter( raster=raster, sigma=sigma, truncate=truncate, size=size, direction=get_enum_values(direction) ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Mexican hat filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # LEE ADDITIVE NOISE FILTER @@ -1036,18 +1028,18 @@ def lee_additive_noise_filter_cli( """Apply a Lee filter considering additive noise components in the input raster.""" from eis_toolkit.raster_processing.filters.speckle import lee_additive_noise_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = lee_additive_noise_filter(raster=raster, size=size, add_noise_var=add_noise_var) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Additive Lee noise filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # LEE MULTIPLICATIVE NOISE FILTER @@ -1062,20 +1054,20 @@ def lee_multiplicative_noise_filter_cli( """Apply a Lee filter considering multiplicative noise components in the input raster.""" from eis_toolkit.raster_processing.filters.speckle import lee_multiplicative_noise_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = lee_multiplicative_noise_filter( raster=raster, size=size, mult_noise_mean=multi_noise_mean, n_looks=n_looks ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Multiplicative Lee noise filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # LEE ADDITIVE MULTIPLICATIVE NOISE FILTER @@ -1091,10 +1083,10 @@ def lee_additive_multiplicative_noise_filter_cli( """Apply a Lee filter considering both additive and multiplicative noise components in the input raster.""" from eis_toolkit.raster_processing.filters.speckle import lee_additive_multiplicative_noise_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = lee_additive_multiplicative_noise_filter( raster=raster, size=size, @@ -1102,13 +1094,13 @@ def lee_additive_multiplicative_noise_filter_cli( add_noise_mean=add_noise_mean, mult_noise_mean=multi_noise_mean, ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Additive multiplicative Lee noise filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # LEE ENHANCED FILTER @@ -1123,20 +1115,20 @@ def lee_enhanced_filter_cli( """Apply an enhanced Lee filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import lee_enhanced_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = lee_enhanced_filter( raster=raster, size=size, n_looks=n_looks, damping_factor=damping_factor ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Enhanced Lee filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # GAMMA FILTER @@ -1150,18 +1142,18 @@ def gamma_filter_cli( """Apply a Gamma filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import gamma_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = gamma_filter(raster=raster, size=size, n_looks=n_looks) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Gamma filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # FROST FILTER @@ -1175,18 +1167,18 @@ def frost_filter_cli( """Apply a Frost filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import frost_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = frost_filter(raster=raster, size=size, damping_factor=damping_factor) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Frost filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # KUAN FILTER @@ -1200,18 +1192,18 @@ def kuan_filter_cli( """Apply a Kuan filter to the input raster.""" from eis_toolkit.raster_processing.filters.speckle import kuan_filter - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = kuan_filter(raster=raster, size=size, n_looks=n_looks) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Kuan filter applied, output raster written to {output_raster}.") + ProgressLog.finish() # CHECK RASTER GRIDS @@ -1220,23 +1212,19 @@ def check_raster_grids_cli(input_rasters: INPUT_FILES_ARGUMENT, same_extent: boo """Check all input rasters for matching gridding and optionally matching bounds.""" from eis_toolkit.utilities.checks.raster import check_raster_grids - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster_profiles = [] + for input_raster in input_rasters: + with rasterio.open(input_raster) as raster: + raster_profiles.append(raster.profile) - raster_profiles = [] - for input_raster in input_rasters: - with rasterio.open(input_raster) as raster: - raster_profiles.append(raster.profile) - typer.echo("Progress: 50%") + with ProgressLog.running_algorithm(): + result = check_raster_grids(raster_profiles=raster_profiles, same_extent=same_extent) - result = check_raster_grids(raster_profiles=raster_profiles, same_extent=same_extent) results_dict = {"result": result} - typer.echo("Progress: 75%") - json_str = json.dumps(results_dict) - typer.echo("Progress: 100%") - - typer.echo(f"Results: {json_str}") - typer.echo("Checking raster grids completed.") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() # CLIP RASTER @@ -1249,23 +1237,22 @@ def clip_raster_cli( """Clip the input raster with geometries in a geodataframe.""" from eis_toolkit.raster_processing.clipping import clip_raster - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(geometries) + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(geometries) + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = clip_raster( raster=raster, geodataframe=geodataframe, ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Clipping completed, output raster written to {output_raster}.") + ProgressLog.finish() # CREATE CONSTANT RASTER MANUALLY @@ -1286,30 +1273,27 @@ def create_constant_raster_manually_cli( """ from eis_toolkit.raster_processing.create_constant_raster import create_constant_raster - typer.echo("Progress: 10%") - - coord_west, coord_east, coord_south, coord_north = extent - raster_width = round(abs(coord_east - coord_west) / target_pixel_size) - raster_height = round(abs(coord_north - coord_south) / target_pixel_size) - out_image, out_meta = create_constant_raster( - constant_value=constant_value, - coord_west=coord_west, - coord_north=coord_north, - coord_east=coord_east, - coord_south=coord_south, - target_epsg=target_epsg, - raster_width=raster_width, - raster_height=raster_height, - nodata_value=nodata_value, - ) - - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + coord_west, coord_east, coord_south, coord_north = extent + raster_width = round(abs(coord_east - coord_west) / target_pixel_size) + raster_height = round(abs(coord_north - coord_south) / target_pixel_size) + out_image, out_meta = create_constant_raster( + constant_value=constant_value, + coord_west=coord_west, + coord_north=coord_north, + coord_east=coord_east, + coord_south=coord_south, + target_epsg=target_epsg, + raster_width=raster_width, + raster_height=raster_height, + nodata_value=nodata_value, + ) - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Creating constant raster completed, writing raster to {output_raster}.") + ProgressLog.finish() # CREATE CONSTANT RASTER FROM TEMPLATE @@ -1323,23 +1307,22 @@ def create_constant_raster_from_template_cli( """Create constant raster from a template raster.""" from eis_toolkit.raster_processing.create_constant_raster import create_constant_raster - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(template_raster) - with rasterio.open(template_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = create_constant_raster( constant_value=constant_value, template_raster=raster, nodata_value=nodata_value, ) + raster.close() - typer.echo("Progress: 75%") - - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Creating constant raster completed, writing raster to {output_raster}.") + ProgressLog.finish() # DISTANCE TO ANOMALY @@ -1361,15 +1344,13 @@ def distance_to_anomaly_cli( from eis_toolkit.raster_processing.distance_to_anomaly import distance_to_anomaly - typer.echo("Progress: 10%") - if second_threshold_criteria_value is not None: threshold_criteria_value = (first_threshold_criteria_value, second_threshold_criteria_value) else: threshold_criteria_value = first_threshold_criteria_value - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) # # Use optimized version if Windows # if platform == "win32": # out_image, out_meta = distance_to_anomaly_gdal( @@ -1380,6 +1361,7 @@ def distance_to_anomaly_cli( # max_distance=max_distance, # ) # else: + with ProgressLog.running_algorithm(): out_image, out_meta = distance_to_anomaly( anomaly_raster_profile=raster.profile, anomaly_raster_data=raster.read(1), @@ -1387,14 +1369,13 @@ def distance_to_anomaly_cli( threshold_criteria=get_enum_values(threshold_criteria), max_distance=max_distance, ) + raster.close() - typer.echo("Progress: 75%") - - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Computing distance to anomaly completed, writing raster to {output_raster}.") + ProgressLog.finish() # PROXIMITY TO ANOMALY @@ -1418,15 +1399,13 @@ def proximity_to_anomaly_cli( from eis_toolkit.raster_processing.proximity_to_anomaly import proximity_to_anomaly - typer.echo("Progress: 10%") - if second_threshold_criteria_value is not None: threshold_criteria_value = (first_threshold_criteria_value, second_threshold_criteria_value) else: threshold_criteria_value = first_threshold_criteria_value - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) # Use optimized version if Windows # if platform == "win32": # out_image, out_meta = proximity_to_anomaly_gdal( @@ -1438,6 +1417,7 @@ def proximity_to_anomaly_cli( # scaling_range=(anomaly_value, max_distance_value), # ) # else: + with ProgressLog.running_algorithm(): out_image, out_meta = proximity_to_anomaly( anomaly_raster_profile=raster.profile, anomaly_raster_data=raster.read(1), @@ -1446,14 +1426,13 @@ def proximity_to_anomaly_cli( max_distance=max_distance, scaling_range=(anomaly_value, max_distance_value), ) + raster.close() - typer.echo("Progress: 75%") - - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Computing proximity to anomaly completed, writing raster to {output_raster}.") + ProgressLog.finish() # EXTRACT VALUES FROM RASTER @@ -1466,19 +1445,18 @@ def extract_values_from_raster_cli( """Extract raster values using point data to a DataFrame.""" from eis_toolkit.raster_processing.extract_values_from_raster import extract_values_from_raster - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(geometries) + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(geometries) + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): df = extract_values_from_raster(raster_list=[raster], geodataframe=geodataframe) - typer.echo("Progress: 75%") + raster.close() - df.to_csv(output_vector) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_vector): + df.to_csv(output_vector) - typer.echo(f"Extracting values from raster completed, writing vector to {output_vector}.") + ProgressLog.finish() # REPROJECT RASTER @@ -1492,20 +1470,20 @@ def reproject_raster_cli( """Reproject the input raster to given CRS.""" from eis_toolkit.raster_processing.reprojecting import reproject_raster - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reproject_raster( raster=raster, target_crs=target_crs, resampling_method=get_enum_values(resampling_method) ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reprojecting completed, writing raster to {output_raster}.") + ProgressLog.finish() # RESAMPLE RASTER @@ -1519,20 +1497,20 @@ def resample_raster_cli( """Resamples raster according to given resolution.""" from eis_toolkit.raster_processing.resampling import resample - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = resample( raster=raster, resolution=resolution, resampling_method=get_enum_values(resampling_method) ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Resampling completed, writing raster to {output_raster}.") + ProgressLog.finish() # SNAP RASTER @@ -1545,18 +1523,20 @@ def snap_raster_cli( """Snaps/aligns input raster to the given snap raster.""" from eis_toolkit.raster_processing.snapping import snap_with_raster - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + src = rasterio.open(input_raster) + snap_src = rasterio.open(snap_raster) - with rasterio.open(input_raster) as src, rasterio.open(snap_raster) as snap_src: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = snap_with_raster(src, snap_src) - typer.echo("Progress: 75%") + src.close() + snap_raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Snapping completed, writing raster to {output_raster}.") + ProgressLog.finish() # UNIFY RASTERS @@ -1571,12 +1551,11 @@ def unify_rasters_cli( """Unify rasters to match the base raster.""" from eis_toolkit.raster_processing.unifying import unify_raster_grids - typer.echo("Progress: 10%") - - with rasterio.open(base_raster) as raster: + with ProgressLog.reading_input_files(): + raster = rasterio.open(base_raster) to_unify = [rasterio.open(rstr) for rstr in rasters_to_unify] # Open all rasters to be unified - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): masking_param = get_enum_values(masking) unified = unify_raster_grids( base_raster=raster, @@ -1584,22 +1563,22 @@ def unify_rasters_cli( resampling_method=get_enum_values(resampling_method), masking=None if masking_param == "none" else masking_param, ) - [rstr.close() for rstr in to_unify] # Close all rasters - typer.echo("Progress: 75%") - - out_rasters_dict = {} - for i, (out_image, out_meta) in enumerate(unified[1:]): # Skip writing base raster - in_raster_name = os.path.splitext(os.path.split(rasters_to_unify[i])[1])[0] - output_raster_name = f"{in_raster_name}_unified" - output_raster_path = output_directory.joinpath(output_raster_name + ".tif") - with rasterio.open(output_raster_path, "w", **out_meta) as dst: - dst.write(out_image) - out_rasters_dict[output_raster_name] = str(output_raster_path) - typer.echo("Progress: 100%") + # Close all rasters + raster.close() + [rstr.close() for rstr in to_unify] - json_str = json.dumps(out_rasters_dict) - typer.echo(f"Output rasters: {json_str}") - typer.echo(f"Unifying completed, rasters saved to {output_directory}.") + with ProgressLog.saving_output_files(output_directory): + out_rasters_dict = {} + for i, (out_image, out_meta) in enumerate(unified[1:]): # Skip writing base raster + in_raster_name = os.path.splitext(os.path.split(rasters_to_unify[i])[1])[0] + output_raster_name = f"{in_raster_name}_unified" + output_raster_path = output_directory.joinpath(output_raster_name + ".tif") + with rasterio.open(output_raster_path, "w", **out_meta) as dst: + dst.write(out_image) + out_rasters_dict[output_raster_name] = str(output_raster_path) + + ResultSender.send_dict_as_json(out_rasters_dict) + ProgressLog.finish() # GET UNIQUE COMBINATIONS @@ -1611,19 +1590,18 @@ def unique_combinations_cli( """Get combinations of raster values between rasters.""" from eis_toolkit.raster_processing.unique_combinations import unique_combinations - typer.echo("Progress: 10%") - rasters = [rasterio.open(rstr) for rstr in input_rasters] + with ProgressLog.reading_input_files(): + rasters = [rasterio.open(rstr) for rstr in input_rasters] - typer.echo("Progress: 25%") - out_image, out_meta = unique_combinations(rasters) - [rstr.close() for rstr in rasters] - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image, out_meta = unique_combinations(rasters) + [rstr.close() for rstr in rasters] - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image, 1) + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image, 1) - typer.echo(f"Writing results to {output_raster}.") - typer.echo("Getting unique combinations completed.") + ProgressLog.finish() # EXTRACT WINDOW @@ -1638,18 +1616,18 @@ def extract_window_cli( """Extract window from raster.""" from eis_toolkit.raster_processing.windowing import extract_window - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = extract_window(raster, center_coords, height, width) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Windowing completed, writing raster to {output_raster}") + ProgressLog.finish() # SURFACE DERIVATIVES - CLASSIFY ASPECT @@ -1663,22 +1641,21 @@ def classify_aspect_cli( """Classify an aspect raster data set.""" from eis_toolkit.raster_processing.derivatives.classification import classify_aspect - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, class_mapping, out_meta = classify_aspect( raster=raster, unit=get_enum_values(unit), num_classes=num_classes ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image, 1) - json_str = json.dumps(class_mapping) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image, 1) - typer.echo(f"Classifying aspect completed, writing raster to {output_raster}") + ResultSender.send_dict_as_json(class_mapping) + ProgressLog.finish() # SURFACE DERIVATIVES @@ -1698,10 +1675,10 @@ def surface_derivatives_cli( """Calculate the first and/or second order surface attributes.""" from eis_toolkit.raster_processing.derivatives.parameters import first_order, second_order_basic_set - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): if first_order_parameters: first_order_results = first_order( raster=raster, @@ -1722,23 +1699,22 @@ def surface_derivatives_cli( slope_tolerance=slope_tolerance, method=get_enum_values(second_order_method), ) - typer.echo("Progres: 75%") + raster.close() - if first_order_parameters: - for parameter, (out_image, out_meta) in first_order_results.items(): - out_raster_name = str(output_raster)[:-4] + "_" + parameter + str(output_raster)[-4:] - with rasterio.open(out_raster_name, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 90%") + with ProgressLog.saving_output_files(output_raster): + if first_order_parameters: + for parameter, (out_image, out_meta) in first_order_results.items(): + out_raster_name = str(output_raster)[:-4] + "_" + parameter + str(output_raster)[-4:] + with rasterio.open(out_raster_name, "w", **out_meta) as dest: + dest.write(out_image, 1) - if second_order_parameters: - for parameter, (out_image, out_meta) in second_order_results.items(): - out_raster_name = str(output_raster)[:-4] + "_" + parameter + str(output_raster)[-4:] - with rasterio.open(out_raster_name, "w", **out_meta) as dest: - dest.write(out_image, 1) - typer.echo("Progress: 100%") + if second_order_parameters: + for parameter, (out_image, out_meta) in second_order_results.items(): + out_raster_name = str(output_raster)[:-4] + "_" + parameter + str(output_raster)[-4:] + with rasterio.open(out_raster_name, "w", **out_meta) as dest: + dest.write(out_image, 1) - typer.echo(f"Calculating first and/or second order surface attributes completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1750,19 +1726,20 @@ def mask_raster_cli( """Mask input raster using the nodata locations from base raster.""" from eis_toolkit.raster_processing.masking import mask_raster - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) + base_rstr = rasterio.open(base_raster) - with rasterio.open(input_raster) as raster: - with rasterio.open(base_raster) as base_rstr: - typer.echo("Progress: 25%") - out_image, out_meta = mask_raster(raster=raster, base_raster=base_rstr) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image, out_meta = mask_raster(raster=raster, base_raster=base_rstr) + raster.close() + base_rstr.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Raster masking completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1775,18 +1752,18 @@ def reclassify_with_manual_breaks_cli( """Classify raster with manual breaks.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_manual_breaks - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_manual_breaks(raster=raster, breaks=breaks, bands=bands) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with manual breaks completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1799,18 +1776,18 @@ def reclassify_with_defined_intervals_cli( """Classify raster with defined intervals.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_defined_intervals - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_defined_intervals(raster=raster, interval_size=interval_size, bands=bands) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with defined intervals completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1823,20 +1800,20 @@ def reclassify_with_equal_intervals_cli( """Classify raster with equal intervals.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_equal_intervals - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_equal_intervals( raster=raster, number_of_intervals=number_of_intervals, bands=bands ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with equal intervals completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1849,20 +1826,20 @@ def reclassify_with_quantiles_cli( """Classify raster with quantiles.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_quantiles - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_quantiles( raster=raster, number_of_quantiles=number_of_quantiles, bands=bands ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with quantiles completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1875,20 +1852,20 @@ def reclassify_with_natural_breaks_cli( """Classify raster with natural breaks (Jenks Caspall).""" from eis_toolkit.raster_processing.reclassify import reclassify_with_natural_breaks - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_natural_breaks( raster=raster, number_of_classes=number_of_classes, bands=bands ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with natural breaks completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1901,20 +1878,20 @@ def reclassify_with_geometrical_intervals_cli( """Classify raster with geometrical intervals.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_geometrical_intervals - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_geometrical_intervals( raster=raster, number_of_classes=number_of_classes, bands=bands ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with geometric intervals completed, writing raster to {output_raster}") + ProgressLog.finish() @app.command() @@ -1927,20 +1904,20 @@ def reclassify_with_standard_deviation_cli( """Classify raster with standard deviation.""" from eis_toolkit.raster_processing.reclassify import reclassify_with_standard_deviation - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = reclassify_with_standard_deviation( raster=raster, number_of_intervals=number_of_intervals, bands=bands ) - typer.echo("Progress: 75%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dest: - dest.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dest: + dest.write(out_image) - typer.echo(f"Reclassification with standard deviation completed, writing raster to {output_raster}") + ProgressLog.finish() # --- VECTOR PROCESSING --- @@ -1952,17 +1929,16 @@ def calculate_geometry_cli(input_vector: INPUT_FILE_OPTION, output_vector: OUTPU """Calculate the length or area of the given geometries.""" from eis_toolkit.vector_processing.calculate_geometry import calculate_geometry - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_vector = calculate_geometry(geodataframe=geodataframe) - out_vector = calculate_geometry(geodataframe=geodataframe) - typer.echo("Progress: 75%") + with ProgressLog.saving_output_files(output_vector): + out_vector.to_file(output_vector) - out_vector.to_file(output_vector) - typer.echo("Progress 100%") - typer.echo(f"Calculate geometry completed, writing vector to {output_vector}") + ProgressLog.finish() # EXTRACT SHARED LINES @@ -1971,17 +1947,16 @@ def extract_shared_lines_cli(input_vector: INPUT_FILE_OPTION, output_vector: OUT """Extract shared lines/borders/edges between polygons.""" from eis_toolkit.vector_processing.extract_shared_lines import extract_shared_lines - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + polygons = gpd.read_file(input_vector) - polygons = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_vector = extract_shared_lines(polygons=polygons) - out_vector = extract_shared_lines(polygons=polygons) - typer.echo("Progress: 75%") + with ProgressLog.saving_output_files(output_vector): + out_vector.to_file(output_vector) - out_vector.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Extracting shared lines completed, writing vector to {out_vector}") + ProgressLog.finish() # IDW INTERPOLATION @@ -2001,40 +1976,38 @@ def idw_interpolation_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.idw_interpolation import idw - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() - - out_image = idw( - geodataframe=geodataframe, - target_column=target_column, - raster_profile=profile, - power=power, - search_radius=search_radius, - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = idw( + geodataframe=geodataframe, + target_column=target_column, + raster_profile=profile, + power=power, + search_radius=search_radius, + ) profile["count"] = 1 - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"IDW interpolation completed, writing raster to {output_raster}.") + ProgressLog.finish() # KRIGING INTERPOLATION @@ -2055,41 +2028,39 @@ def kriging_interpolation_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.kriging_interpolation import kriging - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() - - out_image = kriging( - geodataframe=geodataframe, - target_column=target_column, - raster_profile=profile, - variogram_model=get_enum_values(variogram_model), - coordinates_type=get_enum_values(coordinates_type), - method=get_enum_values(method), - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = kriging( + geodataframe=geodataframe, + target_column=target_column, + raster_profile=profile, + variogram_model=get_enum_values(variogram_model), + coordinates_type=get_enum_values(coordinates_type), + method=get_enum_values(method), + ) profile["count"] = 1 - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Kriging interpolation completed, writing raster to {output_raster}.") + ProgressLog.finish() # RASTERIZE @@ -2115,42 +2086,40 @@ def rasterize_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.rasterize_vector import rasterize_vector - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") - - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() - - out_image = rasterize_vector( - geodataframe, - profile, - value_column, - default_value, - fill_value, - buffer_value, - get_enum_values(merge_strategy), - ) - typer.echo("Progress: 75%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() + + with ProgressLog.running_algorithm(): + out_image = rasterize_vector( + geodataframe, + profile, + value_column, + default_value, + fill_value, + buffer_value, + get_enum_values(merge_strategy), + ) profile["count"] = 1 - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Rasterizing completed, writing raster to {output_raster}.") + ProgressLog.finish() # REPROJECT VECTOR @@ -2163,18 +2132,16 @@ def reproject_vector_cli( """Reproject the input vector to given CRS.""" from eis_toolkit.vector_processing.reproject_vector import reproject_vector - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + reprojected_geodataframe = reproject_vector(geodataframe=geodataframe, target_crs=target_crs) - reprojected_geodataframe = reproject_vector(geodataframe=geodataframe, target_crs=target_crs) - typer.echo("Progress: 75%") + with ProgressLog.saving_output_files(output_vector): + reprojected_geodataframe.to_file(output_vector, driver="GeoJSON") - reprojected_geodataframe.to_file(output_vector, driver="GeoJSON") - typer.echo("Progress: 100%") - - typer.echo(f"Reprojecting completed, writing vector to {output_vector}.") + ProgressLog.finish() # VECTOR DENSITY @@ -2197,39 +2164,37 @@ def vector_density_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.vector_density import vector_density - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") - - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() - out_image = vector_density( - geodataframe=geodataframe, - raster_profile=profile, - buffer_value=buffer_value, - statistic=get_enum_values(statistic), - ) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = vector_density( + geodataframe=geodataframe, + raster_profile=profile, + buffer_value=buffer_value, + statistic=get_enum_values(statistic), + ) profile["count"] = 1 - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Vector density computation completed, writing raster to {output_raster}.") + ProgressLog.finish() # DISTANCE COMPUTATION @@ -2247,34 +2212,32 @@ def distance_computation_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.distance_computation import distance_computation - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") - - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() - out_image = distance_computation(geodataframe=geodataframe, raster_profile=profile, max_distance=max_distance) + with ProgressLog.running_algorithm(): + out_image = distance_computation(geodataframe=geodataframe, raster_profile=profile, max_distance=max_distance) profile["count"] = 1 - typer.echo("Progress: 75%") - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Distance computation completed, writing raster to {output_raster}.") + ProgressLog.finish() # CBA @@ -2291,29 +2254,27 @@ def cell_based_association_cli( """Create a CBA matrix.""" from eis_toolkit.vector_processing.cell_based_association import cell_based_association - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") - - if subset_target_attribute_values is not None: - subset_target_attribute_values = [value.strip() for value in subset_target_attribute_values] - - cell_based_association( - cell_size=cell_size, - geodata=[geodataframe], - output_path=output_raster, - column=column if column is None else [column], - subset_target_attribute_values=subset_target_attribute_values - if subset_target_attribute_values is None - else [subset_target_attribute_values], - add_name=add_name if add_name is None else [add_name], - add_buffer=add_buffer if add_buffer is None else [add_buffer], - ) - - typer.echo("Progress: 100%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if subset_target_attribute_values is not None: + subset_target_attribute_values = [value.strip() for value in subset_target_attribute_values] + + with ProgressLog.running_algorithm(): + cell_based_association( + cell_size=cell_size, + geodata=[geodataframe], + output_path=output_raster, + column=column if column is None else [column], + subset_target_attribute_values=subset_target_attribute_values + if subset_target_attribute_values is None + else [subset_target_attribute_values], + add_name=add_name if add_name is None else [add_name], + add_buffer=add_buffer if add_buffer is None else [add_buffer], + ) - typer.echo(f"Cell based association completed, writing raster to {output_raster}.") + ProgressLog.saving_output_files(output_raster) + ProgressLog.finish() # PROXIMITY COMPUTATION @@ -2333,39 +2294,37 @@ def proximity_computation_cli( from eis_toolkit.utilities.raster import profile_from_extent_and_pixel_size from eis_toolkit.vector_processing.proximity_computation import proximity_computation - typer.echo("Progress: 10%") - - geodataframe = gpd.read_file(input_vector) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + geodataframe = gpd.read_file(input_vector) + + if base_raster is None or base_raster == "": + if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: + raise InvalidParameterValueException( + "Expected positive pixel size and defined extent in absence of base raster. " + + f"Pixel size: {pixel_size}, extent: {extent}." + ) + profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) + profile["crs"] = geodataframe.crs + profile["driver"] = "GTiff" + profile["dtype"] = "float32" + else: + with rasterio.open(base_raster) as raster: + profile = raster.profile.copy() - if base_raster is None or base_raster == "": - if any(bound is None for bound in extent) or pixel_size is None or pixel_size <= 0: - raise InvalidParameterValueException( - "Expected positive pixel size and defined extent in absence of base raster. " - + f"Pixel size: {pixel_size}, extent: {extent}." - ) - profile = profile_from_extent_and_pixel_size(extent, (pixel_size, pixel_size)) - profile["crs"] = geodataframe.crs - profile["driver"] = "GTiff" - profile["dtype"] = "float32" - else: - with rasterio.open(base_raster) as raster: - profile = raster.profile.copy() - - out_image = proximity_computation( - geodataframe=geodataframe, - raster_profile=profile, - maximum_distance=max_distance, - scale_range=(geometries_value, max_distance_value), - ) + with ProgressLog.running_algorithm(): + out_image = proximity_computation( + geodataframe=geodataframe, + raster_profile=profile, + maximum_distance=max_distance, + scale_range=(geometries_value, max_distance_value), + ) profile["count"] = 1 - typer.echo("Progress: 75%") - with rasterio.open(output_raster, "w", **profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Proximity computation completed, writing raster to {output_raster}.") + ProgressLog.finish() # --- PREDICTION --- @@ -2395,36 +2354,30 @@ def logistic_regression_train_cli( from eis_toolkit.prediction.logistic_regression import logistic_regression_train from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = logistic_regression_train( - X=X, - y=y, - validation_method=get_enum_values(validation_method), - metrics=get_enum_values(validation_metrics), - split_size=split_size, - cv_folds=cv_folds, - penalty=get_enum_values(penalty), - max_iter=max_iter, - solver=get_enum_values(solver), - verbose=verbose, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = logistic_regression_train( + X=X, + y=y, + validation_method=get_enum_values(validation_method), + metrics=get_enum_values(validation_metrics), + split_size=split_size, + cv_folds=cv_folds, + penalty=get_enum_values(penalty), + max_iter=max_iter, + solver=get_enum_values(solver), + verbose=verbose, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - typer.echo("Logistic regression training completed") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # RANDOM FOREST CLASSIFIER @@ -2451,36 +2404,30 @@ def random_forest_classifier_train_cli( from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model from eis_toolkit.prediction.random_forests import random_forest_classifier_train - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = random_forest_classifier_train( - X=X, - y=y, - validation_method=get_enum_values(validation_method), - metrics=get_enum_values(validation_metrics), - split_size=split_size, - cv_folds=cv_folds, - n_estimators=n_estimators, - criterion=criterion, - max_depth=max_depth, - verbose=verbose, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = random_forest_classifier_train( + X=X, + y=y, + validation_method=get_enum_values(validation_method), + metrics=get_enum_values(validation_metrics), + split_size=split_size, + cv_folds=cv_folds, + n_estimators=n_estimators, + criterion=criterion, + max_depth=max_depth, + verbose=verbose, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - typer.echo("Random forest classifier training completed") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # RANDOM FOREST REGRESSOR @@ -2505,36 +2452,30 @@ def random_forest_regressor_train_cli( from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model from eis_toolkit.prediction.random_forests import random_forest_regressor_train - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = random_forest_regressor_train( - X=X, - y=y, - validation_method=get_enum_values(validation_method), - metrics=get_enum_values(validation_metrics), - split_size=split_size, - cv_folds=cv_folds, - n_estimators=n_estimators, - criterion=criterion, - max_depth=max_depth, - verbose=verbose, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = random_forest_regressor_train( + X=X, + y=y, + validation_method=get_enum_values(validation_method), + metrics=get_enum_values(validation_metrics), + split_size=split_size, + cv_folds=cv_folds, + n_estimators=n_estimators, + criterion=criterion, + max_depth=max_depth, + verbose=verbose, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - typer.echo("Random forest regressor training completed") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # GRADIENT BOOSTING CLASSIFIER @@ -2563,38 +2504,32 @@ def gradient_boosting_classifier_train_cli( from eis_toolkit.prediction.gradient_boosting import gradient_boosting_classifier_train from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = gradient_boosting_classifier_train( - X=X, - y=y, - validation_method=get_enum_values(validation_method), - metrics=get_enum_values(validation_metrics), - split_size=split_size, - cv_folds=cv_folds, - loss=get_enum_values(loss), - learning_rate=learning_rate, - n_estimators=n_estimators, - max_depth=max_depth, - subsample=subsample, - verbose=verbose, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = gradient_boosting_classifier_train( + X=X, + y=y, + validation_method=get_enum_values(validation_method), + metrics=get_enum_values(validation_metrics), + split_size=split_size, + cv_folds=cv_folds, + loss=get_enum_values(loss), + learning_rate=learning_rate, + n_estimators=n_estimators, + max_depth=max_depth, + subsample=subsample, + verbose=verbose, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - typer.echo("Gradient boosting classifier training completed") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # GRADIENT BOOSTING REGRESSOR @@ -2621,38 +2556,32 @@ def gradient_boosting_regressor_train_cli( from eis_toolkit.prediction.gradient_boosting import gradient_boosting_regressor_train from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = gradient_boosting_regressor_train( - X=X, - y=y, - validation_method=get_enum_values(validation_method), - metrics=get_enum_values(validation_metrics), - split_size=split_size, - cv_folds=cv_folds, - loss=loss, - learning_rate=learning_rate, - n_estimators=n_estimators, - max_depth=max_depth, - subsample=subsample, - verbose=verbose, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = gradient_boosting_regressor_train( + X=X, + y=y, + validation_method=get_enum_values(validation_method), + metrics=get_enum_values(validation_metrics), + split_size=split_size, + cv_folds=cv_folds, + loss=loss, + learning_rate=learning_rate, + n_estimators=n_estimators, + max_depth=max_depth, + subsample=subsample, + verbose=verbose, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) # NOTE: Check if .joblib needs to be added to save path - typer.echo("Gradient boosting regressor training completed") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # MLP CLASSIFIER @@ -2687,42 +2616,36 @@ def mlp_classifier_train_cli( from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model from eis_toolkit.prediction.mlp import train_MLP_classifier - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = train_MLP_classifier( - X=X, - y=y, - neurons=neurons, - activation=get_enum_values(activation), - output_neurons=output_neurons, - last_activation=get_enum_values(last_activation), - epochs=epochs, - batch_size=batch_size, - optimizer=get_enum_values(optimizer), - learning_rate=learning_rate, - loss_function=get_enum_values(loss_function), - dropout_rate=dropout_rate, - early_stopping=early_stopping, - es_patience=es_patience, - metrics=get_enum_values(validation_metrics), - validation_split=validation_split, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = train_MLP_classifier( + X=X, + y=y, + neurons=neurons, + activation=get_enum_values(activation), + output_neurons=output_neurons, + last_activation=get_enum_values(last_activation), + epochs=epochs, + batch_size=batch_size, + optimizer=get_enum_values(optimizer), + learning_rate=learning_rate, + loss_function=get_enum_values(loss_function), + dropout_rate=dropout_rate, + early_stopping=early_stopping, + es_patience=es_patience, + metrics=get_enum_values(validation_metrics), + validation_split=validation_split, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) - typer.echo("MLP classifier training completed.") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # MLP REGRESSOR @@ -2754,42 +2677,36 @@ def mlp_regressor_train_cli( from eis_toolkit.prediction.machine_learning_general import prepare_data_for_ml, save_model from eis_toolkit.prediction.mlp import train_MLP_regressor - X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) - - typer.echo("Progress: 30%") - - # Train (and score) the model - model, metrics_dict = train_MLP_regressor( - X=X, - y=y, - neurons=neurons, - activation=get_enum_values(activation), - output_neurons=output_neurons, - last_activation="linear", - epochs=epochs, - batch_size=batch_size, - optimizer=get_enum_values(optimizer), - learning_rate=learning_rate, - loss_function=get_enum_values(loss_function), - dropout_rate=dropout_rate, - early_stopping=early_stopping, - es_patience=es_patience, - metrics=get_enum_values(validation_metrics), - validation_split=validation_split, - random_state=random_state, - ) - - typer.echo("Progress: 80%") - - save_model(model, output_file) - - typer.echo("Progress: 90%") + with ProgressLog.reading_input_files(): + X, y, _, _ = prepare_data_for_ml(input_rasters, target_labels) + + with ProgressLog.running_algorithm(): + # Train (and score) the model + model, metrics_dict = train_MLP_regressor( + X=X, + y=y, + neurons=neurons, + activation=get_enum_values(activation), + output_neurons=output_neurons, + last_activation="linear", + epochs=epochs, + batch_size=batch_size, + optimizer=get_enum_values(optimizer), + learning_rate=learning_rate, + loss_function=get_enum_values(loss_function), + dropout_rate=dropout_rate, + early_stopping=early_stopping, + es_patience=es_patience, + metrics=get_enum_values(validation_metrics), + validation_split=validation_split, + random_state=random_state, + ) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100%") - typer.echo(f"Results: {json_str}") + with ProgressLog.saving_output_files(output_file): + save_model(model, output_file) - typer.echo("MLP regressor training completed.") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # TEST CLASSIFIER ML MODEL @@ -2808,39 +2725,32 @@ def classifier_test_cli( from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions from eis_toolkit.prediction.machine_learning_predict import predict_classifier - X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels) - typer.echo("Progress: 30%") + with ProgressLog.reading_input_files(): + X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels) + model = load_model(model_file) - model = load_model(model_file) - predictions, probabilities = predict_classifier(X, model, classification_threshold, True) - probabilities_reshaped = reshape_predictions( - probabilities, reference_profile["height"], reference_profile["width"], nodata_mask - ) - predictions_reshaped = reshape_predictions( - predictions, reference_profile["height"], reference_profile["width"], nodata_mask - ) + with ProgressLog.running_algorithm(): + predictions, probabilities = predict_classifier(X, model, classification_threshold, True) + probabilities_reshaped = reshape_predictions( + probabilities, reference_profile["height"], reference_profile["width"], nodata_mask + ) + predictions_reshaped = reshape_predictions( + predictions, reference_profile["height"], reference_profile["width"], nodata_mask + ) - metrics_dict = score_predictions(y, predictions, get_enum_values(test_metrics), decimals=3) - typer.echo("Progress: 80%") + metrics_dict = score_predictions(y, predictions, get_enum_values(test_metrics), decimals=3) out_profile = reference_profile.copy() out_profile.update({"count": 1, "dtype": np.float32}) - with rasterio.open(output_raster_probability, "w", **out_profile) as dst: - dst.write(probabilities_reshaped, 1) - with rasterio.open(output_raster_classified, "w", **out_profile) as dst: - dst.write(predictions_reshaped, 1) + with ProgressLog.saving_output_files([output_raster_probability, output_raster_classified]): + with rasterio.open(output_raster_probability, "w", **out_profile) as dst: + dst.write(probabilities_reshaped, 1) + with rasterio.open(output_raster_classified, "w", **out_profile) as dst: + dst.write(predictions_reshaped, 1) - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100% \n") - - typer.echo(f"Results: {json_str}") - typer.echo( - ( - "Testing classifier model completed, writing rasters to " - f"{output_raster_probability} and {output_raster_classified}." - ) - ) + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # TEST REGRESSOR ML MODEL @@ -2857,29 +2767,27 @@ def regressor_test_cli( from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions from eis_toolkit.prediction.machine_learning_predict import predict_regressor - X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels) - typer.echo("Progress: 30%") + with ProgressLog.reading_input_files(): + X, y, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters, target_labels) + model = load_model(model_file) - model = load_model(model_file) - predictions = predict_regressor(X, model) - predictions_reshaped = reshape_predictions( - predictions, reference_profile["height"], reference_profile["width"], nodata_mask - ) + with ProgressLog.running_algorithm(): + predictions = predict_regressor(X, model) + predictions_reshaped = reshape_predictions( + predictions, reference_profile["height"], reference_profile["width"], nodata_mask + ) - metrics_dict = score_predictions(y, predictions, get_enum_values(test_metrics), decimals=3) - typer.echo("Progress: 80%") + metrics_dict = score_predictions(y, predictions, get_enum_values(test_metrics), decimals=3) out_profile = reference_profile.copy() out_profile.update({"count": 1, "dtype": np.float32}) - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(predictions_reshaped, 1) - - json_str = json.dumps(metrics_dict) - typer.echo("Progress: 100% \n") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(predictions_reshaped, 1) - typer.echo(f"Results: {json_str}") - typer.echo(f"Testing regressor model completed, writing raster to {output_raster}.") + ResultSender.send_dict_as_json(metrics_dict) + ProgressLog.finish() # PREDICT WITH TRAINED ML MODEL @@ -2895,35 +2803,29 @@ def classifier_predict_cli( from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions from eis_toolkit.prediction.machine_learning_predict import predict_classifier - X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters) - - typer.echo("Progress: 30%") + with ProgressLog.reading_input_files(): + X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters) + model = load_model(model_file) - model = load_model(model_file) - predictions, probabilities = predict_classifier(X, model, classification_threshold, True) - probabilities_reshaped = reshape_predictions( - probabilities, reference_profile["height"], reference_profile["width"], nodata_mask - ) - predictions_reshaped = reshape_predictions( - predictions, reference_profile["height"], reference_profile["width"], nodata_mask - ) - typer.echo("Progress: 80%") + with ProgressLog.running_algorithm(): + predictions, probabilities = predict_classifier(X, model, classification_threshold, True) + probabilities_reshaped = reshape_predictions( + probabilities, reference_profile["height"], reference_profile["width"], nodata_mask + ) + predictions_reshaped = reshape_predictions( + predictions, reference_profile["height"], reference_profile["width"], nodata_mask + ) out_profile = reference_profile.copy() out_profile.update({"count": 1, "dtype": np.float32}) - with rasterio.open(output_raster_probability, "w", **out_profile) as dst: - dst.write(probabilities_reshaped, 1) - with rasterio.open(output_raster_classified, "w", **out_profile) as dst: - dst.write(predictions_reshaped, 1) + with ProgressLog.saving_output_files([output_raster_probability, output_raster_classified]): + with rasterio.open(output_raster_probability, "w", **out_profile) as dst: + dst.write(probabilities_reshaped, 1) + with rasterio.open(output_raster_classified, "w", **out_profile) as dst: + dst.write(predictions_reshaped, 1) - typer.echo("Progress: 100%") - typer.echo( - ( - "Predicting with classifier model completed, writing rasters to " - f"{output_raster_probability} and {output_raster_classified}." - ) - ) + ProgressLog.finish() # PREDICT WITH TRAINED ML MODEL @@ -2937,26 +2839,24 @@ def regressor_predict_cli( from eis_toolkit.prediction.machine_learning_general import load_model, prepare_data_for_ml, reshape_predictions from eis_toolkit.prediction.machine_learning_predict import predict_regressor - X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters) - - typer.echo("Progress: 30%") + with ProgressLog.reading_input_files(): + X, _, reference_profile, nodata_mask = prepare_data_for_ml(input_rasters) + model = load_model(model_file) - model = load_model(model_file) - predictions = predict_regressor(X, model) - predictions_reshaped = reshape_predictions( - predictions, reference_profile["height"], reference_profile["width"], nodata_mask - ) - - typer.echo("Progress: 80%") + with ProgressLog.running_algorithm(): + predictions = predict_regressor(X, model) + predictions_reshaped = reshape_predictions( + predictions, reference_profile["height"], reference_profile["width"], nodata_mask + ) out_profile = reference_profile.copy() out_profile.update({"count": 1, "dtype": np.float32}) - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(predictions_reshaped, 1) + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(predictions_reshaped, 1) - typer.echo("Progress: 100%") - typer.echo(f"Predicting with regressor model completed, writing raster to {output_raster}.") + ProgressLog.finish() # FUZZY OVERLAYS @@ -2971,22 +2871,21 @@ def and_overlay_cli( from eis_toolkit.prediction.fuzzy_overlay import and_overlay from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") - - data, profiles = read_and_stack_rasters(input_rasters) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + data, profiles = read_and_stack_rasters(input_rasters) - out_image = and_overlay(data) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = and_overlay(data) out_profile = profiles[0] out_profile["count"] = 1 out_profile["nodata"] = -9999 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") - typer.echo(f"'And' overlay completed, writing raster to {output_raster}.") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(out_image, 1) + + ProgressLog.finish() # OR OVERLAY @@ -2999,22 +2898,21 @@ def or_overlay_cli( from eis_toolkit.prediction.fuzzy_overlay import or_overlay from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + data, profiles = read_and_stack_rasters(input_rasters) - data, profiles = read_and_stack_rasters(input_rasters) - typer.echo("Progress: 25%") - - out_image = or_overlay(data) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = or_overlay(data) out_profile = profiles[0] out_profile["count"] = 1 out_profile["nodata"] = -9999 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") - typer.echo(f"'Or' overlay completed, writing raster to {output_raster}.") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(out_image, 1) + + ProgressLog.finish() # PRODUCT OVERLAY @@ -3027,22 +2925,21 @@ def product_overlay_cli( from eis_toolkit.prediction.fuzzy_overlay import product_overlay from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") - - data, profiles = read_and_stack_rasters(input_rasters) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + data, profiles = read_and_stack_rasters(input_rasters) - out_image = product_overlay(data) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = product_overlay(data) out_profile = profiles[0] out_profile["count"] = 1 out_profile["nodata"] = -9999 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") - typer.echo(f"'Product' overlay completed, writing raster to {output_raster}.") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(out_image, 1) + + ProgressLog.finish() # SUM OVERLAY @@ -3055,22 +2952,21 @@ def sum_overlay_cli( from eis_toolkit.prediction.fuzzy_overlay import sum_overlay from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") - - data, profiles = read_and_stack_rasters(input_rasters) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + data, profiles = read_and_stack_rasters(input_rasters) - out_image = sum_overlay(data) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = sum_overlay(data) out_profile = profiles[0] out_profile["count"] = 1 out_profile["nodata"] = -9999 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") - typer.echo(f"'Sum' overlay completed, writing raster to {output_raster}.") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(out_image, 1) + + ProgressLog.finish() # GAMMA OVERLAY @@ -3080,22 +2976,21 @@ def gamma_overlay_cli(input_rasters: INPUT_FILES_ARGUMENT, output_raster: OUTPUT from eis_toolkit.prediction.fuzzy_overlay import gamma_overlay from eis_toolkit.utilities.file_io import read_and_stack_rasters - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + data, profiles = read_and_stack_rasters(input_rasters) - data, profiles = read_and_stack_rasters(input_rasters) - typer.echo("Progress: 25%") - - out_image = gamma_overlay(data, gamma) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + out_image = gamma_overlay(data, gamma) out_profile = profiles[0] out_profile["count"] = 1 out_profile["nodata"] = -9999 - with rasterio.open(output_raster, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") - typer.echo(f"'Gamma' overlay completed, writing raster to {output_raster}.") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_profile) as dst: + dst.write(out_image, 1) + + ProgressLog.finish() # WOFE @@ -3127,56 +3022,50 @@ def weights_of_evidence_calculate_weights_cli( """ from eis_toolkit.prediction.weights_of_evidence import weights_of_evidence_calculate_weights - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + evidential_raster = rasterio.open(evidential_raster) - evidential_raster = rasterio.open(evidential_raster) - - if deposits.suffix in (".tif", ".tiff", ".asc", ".img", ".vrt", ".grd"): - deposits = rasterio.open(deposits) - else: - deposits = gpd.read_file(deposits) - - typer.echo("Progress: 25%") + if deposits.suffix in (".tif", ".tiff", ".asc", ".img", ".vrt", ".grd"): + deposits = rasterio.open(deposits) + else: + deposits = gpd.read_file(deposits) if arrays_to_generate == []: arrays_to_generate = None - df, arrays, raster_meta, nr_of_deposits, nr_of_pixels = weights_of_evidence_calculate_weights( - evidential_raster=evidential_raster, - deposits=deposits, - raster_nodata=raster_nodata, - weights_type=weights_type, - studentized_contrast_threshold=studentized_contrast_threshold, - arrays_to_generate=arrays_to_generate, - ) - typer.echo("Progress: 75%") - - df.to_csv(output_results_table) - - out_rasters_dict = {} - file_name = evidential_raster.name.split("/")[-1].split(".")[0] - raster_meta.pop("dtype") # Remove dtype from metadata to set it individually - - for key, array in arrays.items(): - # Set correct dtype for the array - if key in ["Class", "Pixel count", "Deposit count"]: - dtype = np.uint8 - else: - dtype = np.float32 + with ProgressLog.running_algorithm(): + df, arrays, raster_meta, nr_of_deposits, nr_of_pixels = weights_of_evidence_calculate_weights( + evidential_raster=evidential_raster, + deposits=deposits, + raster_nodata=raster_nodata, + weights_type=weights_type, + studentized_contrast_threshold=studentized_contrast_threshold, + arrays_to_generate=arrays_to_generate, + ) + + with ProgressLog.saving_output_files([output_raster_dir, output_results_table]): + df.to_csv(output_results_table) - array = nan_to_nodata(array, raster_meta["nodata"]) - output_raster_name = file_name + "_weights_" + weights_type + "_" + key - output_raster_path = output_raster_dir.joinpath(output_raster_name + ".tif") - with rasterio.open(output_raster_path, "w", dtype=dtype, **raster_meta) as dst: - dst.write(array, 1) - out_rasters_dict[output_raster_name] = str(output_raster_path) + out_rasters_dict = {} + file_name = evidential_raster.name.split("/")[-1].split(".")[0] + raster_meta.pop("dtype") # Remove dtype from metadata to set it individually - json_str = json.dumps(out_rasters_dict) - typer.echo("Progress 100%") + for key, array in arrays.items(): + # Set correct dtype for the array + if key in ["Class", "Pixel count", "Deposit count"]: + dtype = np.uint8 + else: + dtype = np.float32 - typer.echo(f"Output rasters: {json_str}") - typer.echo(f"Weight calculations completed, rasters saved to {output_raster_dir}.") - typer.echo(f"Weights table saved to {output_results_table}.") + array = nan_to_nodata(array, raster_meta["nodata"]) + output_raster_name = file_name + "_weights_" + weights_type + "_" + key + output_raster_path = output_raster_dir.joinpath(output_raster_name + ".tif") + with rasterio.open(output_raster_path, "w", dtype=dtype, **raster_meta) as dst: + dst.write(array, 1) + out_rasters_dict[output_raster_name] = str(output_raster_path) + + ResultSender.send_dict_as_json(out_rasters_dict) + ProgressLog.finish() @app.command() @@ -3198,58 +3087,52 @@ def weights_of_evidence_calculate_responses_cli( """ from eis_toolkit.prediction.weights_of_evidence import weights_of_evidence_calculate_responses - typer.echo("Progress: 10%") - typer.echo(input_rasters_weights) - - dict_array = [] - raster_profile = None + with ProgressLog.reading_input_files(): + typer.echo(input_rasters_weights) - for raster_weights, raster_std in zip_longest( - input_rasters_weights, input_rasters_standard_deviations, fillvalue=None - ): + dict_array = [] + raster_profile = None - if raster_weights is not None: - with rasterio.open(raster_weights) as src: - array_W = src.read(1) - array_W = nodata_to_nan(array_W, src.nodata) + for raster_weights, raster_std in zip_longest( + input_rasters_weights, input_rasters_standard_deviations, fillvalue=None + ): - if raster_profile is None: - raster_profile = src.profile + if raster_weights is not None: + with rasterio.open(raster_weights) as src: + array_W = src.read(1) + array_W = nodata_to_nan(array_W, src.nodata) - if raster_std is not None: - with rasterio.open(raster_std) as src: - array_S_W = src.read(1) - array_S_W = nodata_to_nan(array_S_W, src.nodata) + if raster_profile is None: + raster_profile = src.profile - dict_array.append({"W+": array_W, "S_W+": array_S_W}) + if raster_std is not None: + with rasterio.open(raster_std) as src: + array_S_W = src.read(1) + array_S_W = nodata_to_nan(array_S_W, src.nodata) - weights_df = pd.read_csv(input_weights_table) + dict_array.append({"W+": array_W, "S_W+": array_S_W}) - typer.echo("Progress: 25%") + weights_df = pd.read_csv(input_weights_table) - posterior_probabilities, posterior_probabilies_std, confidence_array = weights_of_evidence_calculate_responses( - output_arrays=dict_array, weights_df=weights_df - ) - typer.echo("Progress: 75%") - - posterior_probabilities = nan_to_nodata(posterior_probabilities, raster_profile["nodata"]) - with rasterio.open(output_probabilities, "w", **raster_profile) as dst: - dst.write(posterior_probabilities, 1) + with ProgressLog.running_algorithm(): + posterior_probabilities, posterior_probabilies_std, confidence_array = weights_of_evidence_calculate_responses( + output_arrays=dict_array, weights_df=weights_df + ) - posterior_probabilies_std = nan_to_nodata(posterior_probabilies_std, raster_profile["nodata"]) - with rasterio.open(output_probabilities_std, "w", **raster_profile) as dst: - dst.write(posterior_probabilies_std, 1) + with ProgressLog.saving_output_files([output_probabilities, output_probabilities_std, output_confidence_array]): + posterior_probabilities = nan_to_nodata(posterior_probabilities, raster_profile["nodata"]) + with rasterio.open(output_probabilities, "w", **raster_profile) as dst: + dst.write(posterior_probabilities, 1) - confidence_array = nan_to_nodata(confidence_array, raster_profile["nodata"]) - with rasterio.open(output_confidence_array, "w", **raster_profile) as dst: - dst.write(confidence_array, 1) + posterior_probabilies_std = nan_to_nodata(posterior_probabilies_std, raster_profile["nodata"]) + with rasterio.open(output_probabilities_std, "w", **raster_profile) as dst: + dst.write(posterior_probabilies_std, 1) - typer.echo("Progress: 100%") + confidence_array = nan_to_nodata(confidence_array, raster_profile["nodata"]) + with rasterio.open(output_confidence_array, "w", **raster_profile) as dst: + dst.write(confidence_array, 1) - typer.echo( - f"Posterior probability calculations finished, output rasters saved to {output_probabilities}, \ - {output_probabilities_std} and {output_confidence_array}" - ) + ProgressLog.finish() @app.command() @@ -3261,29 +3144,26 @@ def agterberg_cheng_CI_test_cli( """Perform the conditional independence test presented by Agterberg-Cheng (2002).""" from eis_toolkit.prediction.weights_of_evidence import agterberg_cheng_CI_test - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + with rasterio.open(input_posterior_probabilities) as src: + posterior_probabilities = src.read(1) + posterior_probabilities = nodata_to_nan(posterior_probabilities, src.nodata) - with rasterio.open(input_posterior_probabilities) as src: - posterior_probabilities = src.read(1) - posterior_probabilities = nodata_to_nan(posterior_probabilities, src.nodata) + with rasterio.open(input_posterior_probabilities_std) as src: + posterior_probabilities_std = src.read(1) + posterior_probabilities_std = nodata_to_nan(posterior_probabilities_std, src.nodata) - with rasterio.open(input_posterior_probabilities_std) as src: - posterior_probabilities_std = src.read(1) - posterior_probabilities_std = nodata_to_nan(posterior_probabilities_std, src.nodata) + weights_df = pd.read_csv(input_weights_table) - weights_df = pd.read_csv(input_weights_table) - - typer.echo("Progress: 25%") - - _, _, _, _, summary = agterberg_cheng_CI_test( - posterior_probabilities=posterior_probabilities, - posterior_probabilities_std=posterior_probabilities_std, - weights_df=weights_df, - ) + with ProgressLog.running_algorithm(): + _, _, _, _, summary = agterberg_cheng_CI_test( + posterior_probabilities=posterior_probabilities, + posterior_probabilities_std=posterior_probabilities_std, + weights_df=weights_df, + ) - typer.echo("Progress: 100%") - typer.echo("Conditional independence test completed.") typer.echo(summary) + ProgressLog.finish() # --- TRANSFORMATIONS --- @@ -3300,20 +3180,19 @@ def alr_transform_cli( """Perform an additive logratio transformation on the data.""" from eis_toolkit.transformations.coda.alr import alr_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_df = alr_transform(df=df, column=column, keep_denominator_column=keep_denominator_column) - out_df = alr_transform(df=df, column=column, keep_denominator_column=keep_denominator_column) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) + out_gdf.to_file(output_vector) - out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"ALR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - INVERSE ALR TRANSFORM @@ -3327,20 +3206,19 @@ def inverse_alr_transform_cli( """Perform the inverse transformation for a set of ALR transformed data.""" from eis_toolkit.transformations.coda.alr import inverse_alr - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_df = inverse_alr(df=df, denominator_column=denominator_column, scale=scale) - out_df = inverse_alr(df=df, denominator_column=denominator_column, scale=scale) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) + out_gdf.to_file(output_vector) - out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Inverse ALR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - CLR TRANSFORM @@ -3349,20 +3227,19 @@ def clr_transform_cli(input_vector: INPUT_FILE_OPTION, output_vector: OUTPUT_FIL """Perform a centered logratio transformation on the data.""" from eis_toolkit.transformations.coda.clr import clr_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_df = clr_transform(df=df) - out_df = clr_transform(df=df) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) + out_gdf.to_file(output_vector) - out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"CLR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - INVERSE CLR TRANSFORM @@ -3376,20 +3253,19 @@ def inverse_clr_transform_cli( """Perform the inverse transformation for a set of CLR transformed data.""" from eis_toolkit.transformations.coda.clr import inverse_clr - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_df = inverse_clr(df=df, colnames=colnames, scale=scale) - out_df = inverse_clr(df=df, colnames=colnames, scale=scale) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) + out_gdf.to_file(output_vector) - out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Inverse CLR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - SINGLE ILR TRANSFORM @@ -3403,22 +3279,21 @@ def single_ilr_transform_cli( """Perform a single isometric logratio transformation on the provided subcompositions.""" from eis_toolkit.transformations.coda.ilr import single_ilr_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_series = single_ilr_transform(df=df, subcomposition_1=subcomposition_1, subcomposition_2=subcomposition_2) - out_series = single_ilr_transform(df=df, subcomposition_1=subcomposition_1, subcomposition_2=subcomposition_2) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + # NOTE: Output of pairwise_logratio might be changed to DF in the future, to automatically do the following + df["single_ilr"] = out_series + out_gdf = gpd.GeoDataFrame(df, geometry=geometries) + out_gdf.to_file(output_vector) - # NOTE: Output of pairwise_logratio might be changed to DF in the future, to automatically do the following - df["single_ilr"] = out_series - out_gdf = gpd.GeoDataFrame(df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Single ILR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - PAIRWISE LOGRATIO TRANSFORM @@ -3432,22 +3307,21 @@ def pairwise_logratio_cli( """Perform a pairwise logratio transformation on the given columns.""" from eis_toolkit.transformations.coda.pairwise import pairwise_logratio - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_series = pairwise_logratio(df=df, numerator_column=numerator_column, denominator_column=denominator_column) - out_series = pairwise_logratio(df=df, numerator_column=numerator_column, denominator_column=denominator_column) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + # NOTE: Output of pairwise_logratio might be changed to DF in the future, to automatically do the following + df["pairwise_logratio"] = out_series + out_gdf = gpd.GeoDataFrame(df, geometry=geometries) + out_gdf.to_file(output_vector) - # NOTE: Output of pairwise_logratio might be changed to DF in the future, to automatically do the following - df["pairwise_logratio"] = out_series - out_gdf = gpd.GeoDataFrame(df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Pairwise logratio transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - SINGLE PLR TRANSFORM @@ -3460,22 +3334,21 @@ def single_plr_transform_cli( """Perform a pivot logratio transformation on the selected column.""" from eis_toolkit.transformations.coda.plr import single_plr_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_series = single_plr_transform(df=df, column=column) - out_series = single_plr_transform(df=df, column=column) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + # NOTE: Output of single_plr_transform might be changed to DF in the future, to automatically do the following + df["single_plr"] = out_series + out_gdf = gpd.GeoDataFrame(df, geometry=geometries) + out_gdf.to_file(output_vector) - # NOTE: Output of single_plr_transform might be changed to DF in the future, to automatically do the following - df["single_plr"] = out_series - out_gdf = gpd.GeoDataFrame(df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"Single PLR transform completed, output saved to {output_vector}") + ProgressLog.finish() # CODA - PLR TRANSFORM @@ -3484,20 +3357,19 @@ def plr_transform_cli(input_vector: INPUT_FILE_OPTION, output_vector: OUTPUT_FIL """Perform a pivot logratio transformation on the dataframe, returning the full set of transforms.""" from eis_toolkit.transformations.coda.plr import plr_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + gdf = gpd.read_file(input_vector) + geometries = gdf["geometry"] + df = pd.DataFrame(gdf.drop(columns="geometry")) - gdf = gpd.read_file(input_vector) - geometries = gdf["geometry"] - df = pd.DataFrame(gdf.drop(columns="geometry")) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + out_df = plr_transform(df=df) - out_df = plr_transform(df=df) - typer.echo("Progess 75%") + with ProgressLog.saving_output_files(output_vector): + out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) + out_gdf.to_file(output_vector) - out_gdf = gpd.GeoDataFrame(out_df, geometry=geometries) - out_gdf.to_file(output_vector) - typer.echo("Progress: 100%") - typer.echo(f"PLR transform completed, output saved to {output_vector}") + ProgressLog.finish() # BINARIZE @@ -3515,18 +3387,18 @@ def binarize_cli( """ from eis_toolkit.transformations.binarize import binarize - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = binarize(raster=raster, thresholds=[threshold]) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Binarizing completed, writing raster to {output_raster}.") + ProgressLog.finish() # CLIP TRANSFORM @@ -3545,18 +3417,18 @@ def clip_transform_cli( """ from eis_toolkit.transformations.clip import clip_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = clip_transform(raster=raster, limits=[(limit_lower, limit_higher)]) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Clip transform completed, writing raster to {output_raster}.") + ProgressLog.finish() # Z-SCORE NORMALIZATION @@ -3572,18 +3444,18 @@ def z_score_normalization_cli( """ from eis_toolkit.transformations.linear import z_score_normalization - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = z_score_normalization(raster=raster) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Z-score normalization completed, writing raster to {output_raster}.") + ProgressLog.finish() # MIX_MAX SCALING @@ -3601,18 +3473,18 @@ def min_max_scaling_cli( """ from eis_toolkit.transformations.linear import min_max_scaling - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = min_max_scaling(raster=raster, new_range=[(min, max)]) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Min-max scaling completed, writing raster to {output_raster}.") + ProgressLog.finish() # LOGARITHMIC @@ -3630,18 +3502,18 @@ def log_transform_cli( """ from eis_toolkit.transformations.logarithmic import log_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = log_transform(raster=raster, log_transform=[get_enum_values(log_type)]) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Logarithm transform completed, writing raster to {output_raster}.") + ProgressLog.finish() # SIGMOID @@ -3661,20 +3533,20 @@ def sigmoid_transform_cli( """ from eis_toolkit.transformations.sigmoid import sigmoid_transform - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = sigmoid_transform( raster=raster, bounds=[(limit_lower, limit_upper)], slope=[slope], center=center ) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Sigmoid transform completed, writing raster to {output_raster}.") + ProgressLog.finish() # WINSORIZE @@ -3704,20 +3576,20 @@ def winsorize_transform_cli( """ from eis_toolkit.transformations.winsorize import winsorize - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta, _ = winsorize( raster=raster, percentiles=[(percentile_lower, percentile_higher)], inside=inside ) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Winsorize transform completed, writing raster to {output_raster}.") + ProgressLog.finish() # ---EVALUATION --- @@ -3733,19 +3605,14 @@ def summarize_probability_metrics_cli(true_labels: INPUT_FILE_OPTION, probabilit from eis_toolkit.evaluation.classification_probability_evaluation import summarize_probability_metrics from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): + results_dict = summarize_probability_metrics(y_true=y_true, y_prob=y_prob, decimals=3) - results_dict = summarize_probability_metrics(y_true=y_true, y_prob=y_prob, decimals=3) - - typer.echo("Progress: 75%") - - typer.echo("Progress: 100% \n") - - typer.echo(f"Results: {str(results_dict)}") - typer.echo("\nGenerating probability metrics summary completed.") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() @app.command() @@ -3759,18 +3626,14 @@ def summarize_label_metrics_binary_cli(true_labels: INPUT_FILE_OPTION, predictio from eis_toolkit.evaluation.classification_label_evaluation import summarize_label_metrics_binary from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") - - (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - results_dict = summarize_label_metrics_binary(y_true=y_true, y_pred=y_pred, decimals=3) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + results_dict = summarize_label_metrics_binary(y_true=y_true, y_pred=y_pred, decimals=3) - typer.echo("Progress: 100% \n") - - typer.echo(f"Results: {str(results_dict)}") - typer.echo("\nGenerating prediction label metrics summary completed.") + ResultSender.send_dict_as_json(results_dict) + ProgressLog.finish() @app.command() @@ -3792,24 +3655,21 @@ def plot_roc_curve_cli( from eis_toolkit.evaluation.classification_probability_evaluation import plot_roc_curve from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") - - (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - _ = plot_roc_curve(y_true=y_true, y_prob=y_prob) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + _ = plot_roc_curve(y_true=y_true, y_prob=y_prob) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("ROC curve plot completed") + ProgressLog.finish() @app.command() @@ -3833,24 +3693,21 @@ def plot_det_curve_cli( from eis_toolkit.evaluation.classification_probability_evaluation import plot_det_curve from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") - - (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - _ = plot_det_curve(y_true=y_true, y_prob=y_prob) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + _ = plot_det_curve(y_true=y_true, y_prob=y_prob) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("DET curve plot completed") + ProgressLog.finish() @app.command() @@ -3873,24 +3730,21 @@ def plot_precision_recall_curve_cli( from eis_toolkit.evaluation.classification_probability_evaluation import plot_precision_recall_curve from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - typer.echo("Progress: 25%") - - _ = plot_precision_recall_curve(y_true=y_true, y_prob=y_prob) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + _ = plot_precision_recall_curve(y_true=y_true, y_prob=y_prob) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("Precision-Recall curve plot completed") + ProgressLog.finish() @app.command() @@ -3913,24 +3767,21 @@ def plot_calibration_curve_cli( from eis_toolkit.evaluation.classification_probability_evaluation import plot_calibration_curve from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") - - (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + (y_prob, y_true), _, _ = read_data_for_evaluation([probabilities, true_labels]) - _ = plot_calibration_curve(y_true=y_true, y_prob=y_prob, n_bins=n_bins) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + _ = plot_calibration_curve(y_true=y_true, y_prob=y_prob, n_bins=n_bins) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("Calibration curve plot completed") + ProgressLog.finish() @app.command() @@ -3948,25 +3799,22 @@ def plot_confusion_matrix_cli( from eis_toolkit.evaluation.plot_confusion_matrix import plot_confusion_matrix from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - typer.echo("Progress: 25%") - - matrix = confusion_matrix(y_true, y_pred) - _ = plot_confusion_matrix(confusion_matrix=matrix) - typer.echo("Progress: 75%") + with ProgressLog.running_algorithm(): + matrix = confusion_matrix(y_true, y_pred) + _ = plot_confusion_matrix(confusion_matrix=matrix) if output_file is not None: - dpi = "figure" if save_dpi is None else save_dpi - plt.savefig(output_file, dpi=dpi) - typer.echo(f"Output figure saved to {output_file}.") + with ProgressLog.saving_output_files(output_file): + dpi = "figure" if save_dpi is None else save_dpi + plt.savefig(output_file, dpi=dpi) if show_plot: plt.show() - typer.echo("Progress: 100%") - typer.echo("Confusion matrix plot completed.") + ProgressLog.finish() @app.command() @@ -3980,16 +3828,14 @@ def score_predictions_cli( from eis_toolkit.evaluation.scoring import score_predictions from eis_toolkit.prediction.machine_learning_general import read_data_for_evaluation - typer.echo("Progress: 10%") - - (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + (y_pred, y_true), _, _ = read_data_for_evaluation([predictions, true_labels]) - outputs = score_predictions(y_true, y_pred, metrics, decimals) - typer.echo("Progress: 100% \n") + with ProgressLog.running_algorithm(): + outputs = score_predictions(y_true, y_pred, metrics, decimals) - typer.echo(f"Results: {str(outputs)}") - typer.echo("\nScoring predictions completed.") + ResultSender.send_dict_as_json(outputs) + ProgressLog.finish() # --- UTILITIES --- @@ -3999,21 +3845,21 @@ def split_raster_bands_cli(input_raster: INPUT_FILE_OPTION, output_dir: OUTPUT_D from eis_toolkit.utilities.file_io import get_output_paths_from_common_name from eis_toolkit.utilities.raster import split_raster_bands - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): output_singleband_rasters = split_raster_bands(raster) - typer.echo("Progress: 70%") + raster.close() - name = os.path.splitext(os.path.basename(input_raster))[0] - output_paths = get_output_paths_from_common_name(output_singleband_rasters, output_dir, f"{name}_split", ".tif") - for output_path, (out_image, out_profile) in zip(output_paths, output_singleband_rasters): - with rasterio.open(output_path, "w", **out_profile) as dst: - dst.write(out_image, 1) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_dir): + name = os.path.splitext(os.path.basename(input_raster))[0] + output_paths = get_output_paths_from_common_name(output_singleband_rasters, output_dir, f"{name}_split", ".tif") + for output_path, (out_image, out_profile) in zip(output_paths, output_singleband_rasters): + with rasterio.open(output_path, "w", **out_profile) as dst: + dst.write(out_image, 1) - typer.echo(f"Splitting raster completed, writing rasters to directory {output_dir}.") + ProgressLog.finish() @app.command() @@ -4021,20 +3867,18 @@ def combine_raster_bands_cli(input_rasters: INPUT_FILES_ARGUMENT, output_raster: """Combine multiple rasters into one multiband raster.""" from eis_toolkit.utilities.raster import combine_raster_bands - typer.echo("Progress: 10%") - - rasters = [rasterio.open(raster) for raster in input_rasters] # Open all rasters to be combined - typer.echo("Progress: 25%") + with ProgressLog.reading_input_files(): + rasters = [rasterio.open(raster) for raster in input_rasters] # Open all rasters to be combined - out_image, out_meta = combine_raster_bands(rasters) + with ProgressLog.running_algorithm(): + out_image, out_meta = combine_raster_bands(rasters) [raster.close() for raster in rasters] - typer.echo("Progress: 70%") - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Combining rasters completed, writing raster to {output_raster}.") + ProgressLog.finish() @app.command() @@ -4045,22 +3889,20 @@ def unify_raster_nodata_cli( from eis_toolkit.utilities.file_io import get_output_paths_from_inputs from eis_toolkit.utilities.nodata import unify_raster_nodata - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + rasters = [rasterio.open(raster) for raster in input_rasters] # Open all rasters to be unified - rasters = [rasterio.open(raster) for raster in input_rasters] # Open all rasters to be unified - typer.echo("Progress: 25%") - - unified = unify_raster_nodata(rasters, new_nodata) + with ProgressLog.running_algorithm(): + unified = unify_raster_nodata(rasters, new_nodata) [raster.close() for raster in rasters] - typer.echo("Progress: 70%") - output_paths = get_output_paths_from_inputs(input_rasters, output_dir, "nodata_unified", ".tif") - for output_path, (out_image, out_profile) in zip(output_paths, unified): - with rasterio.open(output_path, "w", **out_profile) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_dir): + output_paths = get_output_paths_from_inputs(input_rasters, output_dir, "nodata_unified", ".tif") + for output_path, (out_image, out_profile) in zip(output_paths, unified): + with rasterio.open(output_path, "w", **out_profile) as dst: + dst.write(out_image) - typer.echo(f"Unifying nodata completed, writing rasters to directory {output_dir}.") + ProgressLog.finish() @app.command() @@ -4073,18 +3915,18 @@ def convert_raster_nodata_cli( """Convert existing nodata values with a new nodata value for a raster.""" from eis_toolkit.utilities.nodata import convert_raster_nodata - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = convert_raster_nodata(raster, old_nodata, new_nodata) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Converting nodata completed, writing raster to {output_raster}.") + ProgressLog.finish() @app.command() @@ -4098,18 +3940,18 @@ def replace_with_nodata_cli( """Replace raster pixel values with nodata.""" from eis_toolkit.utilities.nodata import replace_with_nodata - typer.echo("Progress: 10%") + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) - with rasterio.open(input_raster) as raster: - typer.echo("Progress: 25%") + with ProgressLog.running_algorithm(): out_image, out_meta = replace_with_nodata(raster, target_value, nodata_value, replace_condition) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progres: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Raster pixel values replaced with nodata, writing raster to {output_raster}.") + ProgressLog.finish() @app.command() @@ -4119,19 +3961,19 @@ def set_raster_nodata_cli( """Set new nodata value for raster profile.""" from eis_toolkit.utilities.nodata import set_raster_nodata - typer.echo("Progress: 10%") - - with rasterio.open(input_raster) as raster: + with ProgressLog.reading_input_files(): + raster = rasterio.open(input_raster) out_image = raster.read() - typer.echo("Progress: 25%") + + with ProgressLog.running_algorithm(): out_meta = set_raster_nodata(raster.meta, new_nodata) - typer.echo("Progress: 70%") + raster.close() - with rasterio.open(output_raster, "w", **out_meta) as dst: - dst.write(out_image) - typer.echo("Progress: 100%") + with ProgressLog.saving_output_files(output_raster): + with rasterio.open(output_raster, "w", **out_meta) as dst: + dst.write(out_image) - typer.echo(f"Setting nodata completed, writing raster to {output_raster}.") + ProgressLog.finish() # if __name__ == "__main__":