7
7
import json
8
8
import os
9
9
from enum import Enum
10
+ from itertools import zip_longest
10
11
from pathlib import Path
11
12
12
13
import geopandas as gpd
@@ -332,6 +333,15 @@ class KerasRegressorMetrics(str, Enum):
332
333
mae = "mae"
333
334
334
335
336
+ class WeightsType (str , Enum ):
337
+ """Weights type for WofE."""
338
+
339
+ unique = "unique"
340
+ categorical = "categorical"
341
+ ascending = "ascending"
342
+ descending = "descending"
343
+
344
+
335
345
INPUT_FILE_OPTION = Annotated [
336
346
Path ,
337
347
typer .Option (
@@ -344,6 +354,18 @@ class KerasRegressorMetrics(str, Enum):
344
354
),
345
355
]
346
356
357
+ INPUT_FILES_OPTION = Annotated [
358
+ List [Path ],
359
+ typer .Option (
360
+ exists = True ,
361
+ file_okay = True ,
362
+ dir_okay = False ,
363
+ writable = False ,
364
+ readable = True ,
365
+ resolve_path = True ,
366
+ ),
367
+ ]
368
+
347
369
INPUT_FILES_ARGUMENT = Annotated [
348
370
List [Path ],
349
371
typer .Argument (
@@ -3065,7 +3087,159 @@ def gamma_overlay_cli(input_rasters: INPUT_FILES_ARGUMENT, output_raster: OUTPUT
3065
3087
3066
3088
3067
3089
# WOFE
3068
- # TODO
3090
+ @app .command ()
3091
+ def weights_of_evidence_calculate_weights_cli (
3092
+ input_raster : INPUT_FILE_OPTION ,
3093
+ input_vector : INPUT_FILE_OPTION ,
3094
+ output_dir : OUTPUT_DIR_OPTION ,
3095
+ raster_nodata : Optional [float ] = None ,
3096
+ weights_type : Annotated [WeightsType , typer .Option (case_sensitive = False )] = WeightsType .unique ,
3097
+ studentized_contrast_threshold : float = 1 ,
3098
+ arrays_to_generate : Annotated [Optional [List [str ]], typer .Option ()] = None ,
3099
+ ):
3100
+ """
3101
+ Calculate weights of spatial associations.
3102
+
3103
+ Parameter --studentized-contrast-threshold is used with 'categorical', 'ascending' and 'descending' weight types.
3104
+
3105
+ Parameter --arrays-to-generate controls which columns in the weights dataframe are returned as arrays. All column
3106
+ names in the produced weights_df are valid choices. The available columns for "unique" weights_type are "Class",
3107
+ "Pixel count", "Deposit count", "W+", "S_W+", "W-", "S_W-", "Contrast", "S_Contrast", and "Studentized contrast".
3108
+ For other weights types, additional available column names are "Generalized class", "Generalized W+", and
3109
+ "Generalized S_W+". Defaults to ["Class", "W+", "S_W+] for "unique" weights_type and ["Class", "W+", "S_W+",
3110
+ "Generalized W+", "Generalized S_W+"] for the cumulative weight types.
3111
+ """
3112
+ from eis_toolkit .prediction .weights_of_evidence import weights_of_evidence_calculate_weights
3113
+
3114
+ typer .echo ("Progress: 10%" )
3115
+
3116
+ evidential_raster = rasterio .open (input_raster )
3117
+ deposits = gpd .read_file (input_vector )
3118
+ typer .echo ("Progress: 25%" )
3119
+
3120
+ if arrays_to_generate == []:
3121
+ arrays_to_generate = None
3122
+
3123
+ df , arrays , raster_meta , nr_of_deposits , nr_of_pixels = weights_of_evidence_calculate_weights (
3124
+ evidential_raster = evidential_raster ,
3125
+ deposits = deposits ,
3126
+ raster_nodata = raster_nodata ,
3127
+ weights_type = weights_type ,
3128
+ studentized_contrast_threshold = studentized_contrast_threshold ,
3129
+ arrays_to_generate = arrays_to_generate ,
3130
+ )
3131
+ typer .echo ("Progress: 75%" )
3132
+
3133
+ df .to_csv (output_dir .joinpath ("wofe_results.csv" ))
3134
+
3135
+ file_name = input_raster .name .split ("." )[0 ]
3136
+ for key , array in arrays .items ():
3137
+ output_raster_path = output_dir .joinpath (file_name + "_weights_" + weights_type + "_" + key + ".tif" )
3138
+ with rasterio .open (output_raster_path , "w" , ** raster_meta ) as dst :
3139
+ dst .write (array , 1 )
3140
+
3141
+ typer .echo ("Progress 100%" )
3142
+
3143
+ typer .echo (f"Number of deposit pixels: { nr_of_deposits } " )
3144
+ typer .echo (f"Number of all evidence pixels: { nr_of_pixels } " )
3145
+ typer .echo (f"Weight calculations completed, rasters and CSV saved to { output_dir } ." )
3146
+
3147
+
3148
+ @app .command ()
3149
+ def weights_of_evidence_calculate_responses_cli (
3150
+ input_rasters_weights : INPUT_FILES_OPTION ,
3151
+ input_rasters_standard_deviations : INPUT_FILES_OPTION ,
3152
+ output_probabilities : OUTPUT_FILE_OPTION ,
3153
+ output_probabilities_std : OUTPUT_FILE_OPTION ,
3154
+ output_confidence_array : OUTPUT_FILE_OPTION ,
3155
+ nr_of_deposits : Annotated [int , typer .Option ()],
3156
+ nr_of_pixels : Annotated [int , typer .Option ()],
3157
+ ):
3158
+ """
3159
+ Calculate the posterior probabilities for the given generalized weight arrays.
3160
+
3161
+ Parameter --input-rasters are the output arrays (rasters) of weights-of-evidence-calculate-weights-cli.
3162
+ For each set of rasters, generalized weight and generalized standard deviation arrays are used and summed
3163
+ together pixel-wise to calculate the posterior probabilities. If generalized arrays are not found,
3164
+ the W+ and S_W+ arrays are used (so if outputs from unique weight calculations are used for this function).
3165
+ """
3166
+ from eis_toolkit .prediction .weights_of_evidence import weights_of_evidence_calculate_responses
3167
+
3168
+ typer .echo ("Progress: 10%" )
3169
+ typer .echo (input_rasters_weights )
3170
+
3171
+ dict_array = []
3172
+ raster_profile = None
3173
+
3174
+ for raster_weights , raster_std in zip_longest (
3175
+ input_rasters_weights , input_rasters_standard_deviations , fillvalue = None
3176
+ ):
3177
+
3178
+ if raster_weights is not None :
3179
+ with rasterio .open (raster_weights ) as src :
3180
+ array_W = src .read (1 )
3181
+
3182
+ if raster_profile is None :
3183
+ raster_profile = src .profile
3184
+
3185
+ if raster_std is not None :
3186
+ with rasterio .open (raster_std ) as src :
3187
+ array_S_W = src .read (1 )
3188
+
3189
+ dict_array .append ({"W+" : array_W , "S_W+" : array_S_W })
3190
+
3191
+ typer .echo ("Progress: 25%" )
3192
+
3193
+ posterior_probabilities , posterior_probabilies_std , confidence_array = weights_of_evidence_calculate_responses (
3194
+ output_arrays = dict_array , nr_of_deposits = nr_of_deposits , nr_of_pixels = nr_of_pixels
3195
+ )
3196
+ typer .echo ("Progress: 75%" )
3197
+
3198
+ with rasterio .open (output_probabilities , "w" , ** raster_profile ) as dst :
3199
+ dst .write (posterior_probabilities , 1 )
3200
+
3201
+ with rasterio .open (output_probabilities_std , "w" , ** raster_profile ) as dst :
3202
+ dst .write (posterior_probabilies_std , 1 )
3203
+
3204
+ with rasterio .open (output_confidence_array , "w" , ** raster_profile ) as dst :
3205
+ dst .write (confidence_array , 1 )
3206
+
3207
+ typer .echo ("Progress: 100%" )
3208
+
3209
+ typer .echo (
3210
+ f"Responses calculations finished, writing output rasters to { output_probabilities } , \
3211
+ { output_probabilities_std } and { output_confidence_array } "
3212
+ )
3213
+
3214
+
3215
+ @app .command ()
3216
+ def agterberg_cheng_CI_test_cli (
3217
+ input_posterior_probabilities : INPUT_FILE_OPTION ,
3218
+ input_posterior_probabilities_std : INPUT_FILE_OPTION ,
3219
+ nr_of_deposits : Annotated [int , typer .Option ()],
3220
+ ):
3221
+ """Perform the conditional independence test presented by Agterberg-Cheng (2002)."""
3222
+ from eis_toolkit .prediction .weights_of_evidence import agterberg_cheng_CI_test
3223
+
3224
+ typer .echo ("Progress: 10%" )
3225
+
3226
+ with rasterio .open (input_posterior_probabilities ) as src :
3227
+ posterior_probabilities = src .read (1 )
3228
+
3229
+ with rasterio .open (input_posterior_probabilities_std ) as src :
3230
+ posterior_probabilities_std = src .read (1 )
3231
+
3232
+ typer .echo ("Progress: 25%" )
3233
+
3234
+ _ , _ , _ , _ , summary = agterberg_cheng_CI_test (
3235
+ posterior_probabilities = posterior_probabilities ,
3236
+ posterior_probabilities_std = posterior_probabilities_std ,
3237
+ nr_of_deposits = nr_of_deposits ,
3238
+ )
3239
+
3240
+ typer .echo ("Progress: 100%" )
3241
+ typer .echo ("Conditional independence test completed." )
3242
+ typer .echo (summary )
3069
3243
3070
3244
3071
3245
# --- TRANSFORMATIONS ---
0 commit comments