fimeval 0.1.55__tar.gz → 0.1.56__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fimeval-0.1.55 → fimeval-0.1.56}/PKG-INFO +1 -1
- {fimeval-0.1.55 → fimeval-0.1.56}/pyproject.toml +1 -1
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/BuildingFootprint/evaluationwithBF.py +107 -52
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/evaluationFIM.py +2 -1
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/plotevaluationmetrics.py +25 -21
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval.egg-info/PKG-INFO +1 -1
- {fimeval-0.1.55 → fimeval-0.1.56}/tests/test_evaluationfim.py +0 -2
- {fimeval-0.1.55 → fimeval-0.1.56}/LICENSE.txt +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/README.md +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/setup.cfg +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/BuildingFootprint/__init__.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/BuildingFootprint/microsoftBF.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/PWBs3.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/__init__.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/methods.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/metrics.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/ContingencyMap/printcontingency.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/__init__.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval/utilis.py +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval.egg-info/SOURCES.txt +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval.egg-info/dependency_links.txt +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval.egg-info/requires.txt +0 -0
- {fimeval-0.1.55 → fimeval-0.1.56}/src/fimeval.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fimeval
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.56
|
|
4
4
|
Summary: A Framework for Automatic Evaluation of Flood Inundation Mapping Predictions Evaluation
|
|
5
5
|
Author: Surface Dynamics Modeling Lab
|
|
6
6
|
Author-email: Supath Dhital <sdhital@crimson.ua.edu>, Dipshika Devi <ddevi@ua.edu>
|
|
@@ -8,6 +8,7 @@ from plotly.subplots import make_subplots
|
|
|
8
8
|
import plotly.graph_objects as go
|
|
9
9
|
import seaborn as sns
|
|
10
10
|
import matplotlib.pyplot as plt
|
|
11
|
+
import matplotlib.gridspec as gridspec
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def Changeintogpkg(input_path, output_dir, layer_name):
|
|
@@ -21,8 +22,8 @@ def Changeintogpkg(input_path, output_dir, layer_name):
|
|
|
21
22
|
output_gpkg = os.path.join(output_dir, f"{layer_name}.gpkg")
|
|
22
23
|
gdf.to_file(output_gpkg, driver="GPKG")
|
|
23
24
|
return output_gpkg
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
|
|
26
27
|
def GetFloodedBuildingCountInfo(
|
|
27
28
|
building_fp_path,
|
|
28
29
|
study_area_path,
|
|
@@ -76,8 +77,12 @@ def GetFloodedBuildingCountInfo(
|
|
|
76
77
|
|
|
77
78
|
count_centroids_in_contingency(contingency_map)
|
|
78
79
|
|
|
79
|
-
centroid_counts["Candidate"] =
|
|
80
|
-
|
|
80
|
+
centroid_counts["Candidate"] = (
|
|
81
|
+
centroid_counts["True Positive"] + centroid_counts["False Positive"]
|
|
82
|
+
)
|
|
83
|
+
centroid_counts["Benchmark"] = (
|
|
84
|
+
centroid_counts["True Positive"] + centroid_counts["False Negative"]
|
|
85
|
+
)
|
|
81
86
|
|
|
82
87
|
total_buildings = len(clipped_buildings)
|
|
83
88
|
percentages = {
|
|
@@ -93,7 +98,9 @@ def GetFloodedBuildingCountInfo(
|
|
|
93
98
|
FAR = FP / (TP + FP) if (TP + FP) > 0 else 0
|
|
94
99
|
POD = TP / (TP + FN) if (TP + FN) > 0 else 0
|
|
95
100
|
if centroid_counts["Benchmark"] > 0:
|
|
96
|
-
BDR = (
|
|
101
|
+
BDR = (
|
|
102
|
+
centroid_counts["Candidate"] - centroid_counts["Benchmark"]
|
|
103
|
+
) / centroid_counts["Benchmark"]
|
|
97
104
|
else:
|
|
98
105
|
BDR = 0
|
|
99
106
|
|
|
@@ -122,7 +129,9 @@ def GetFloodedBuildingCountInfo(
|
|
|
122
129
|
],
|
|
123
130
|
}
|
|
124
131
|
counts_df = pd.DataFrame(counts_data)
|
|
125
|
-
csv_file_path = os.path.join(
|
|
132
|
+
csv_file_path = os.path.join(
|
|
133
|
+
save_dir, "EvaluationMetrics", f"BuildingCounts_{basename}.csv"
|
|
134
|
+
)
|
|
126
135
|
os.makedirs(os.path.dirname(csv_file_path), exist_ok=True)
|
|
127
136
|
counts_df.to_csv(csv_file_path, index=False)
|
|
128
137
|
|
|
@@ -135,98 +144,146 @@ def GetFloodedBuildingCountInfo(
|
|
|
135
144
|
]
|
|
136
145
|
|
|
137
146
|
fig = make_subplots(
|
|
138
|
-
rows=1,
|
|
139
|
-
|
|
147
|
+
rows=1,
|
|
148
|
+
cols=2,
|
|
149
|
+
subplot_titles=(
|
|
150
|
+
"Building Counts on Different FIMs",
|
|
151
|
+
"Contingency Flooded Building Counts",
|
|
152
|
+
),
|
|
140
153
|
)
|
|
141
154
|
|
|
142
155
|
fig.add_trace(
|
|
143
156
|
go.Bar(
|
|
144
|
-
x=["Candidate"],
|
|
145
|
-
|
|
146
|
-
|
|
157
|
+
x=["Candidate"],
|
|
158
|
+
y=[centroid_counts["Candidate"]],
|
|
159
|
+
text=[f"{centroid_counts['Candidate']}"],
|
|
160
|
+
textposition="auto",
|
|
161
|
+
marker_color="#1c83eb",
|
|
162
|
+
marker_line_color="black",
|
|
163
|
+
marker_line_width=1,
|
|
147
164
|
name=f"Candidate ({percentages['Candidate']:.2f}%)",
|
|
148
165
|
),
|
|
149
|
-
row=1,
|
|
166
|
+
row=1,
|
|
167
|
+
col=1,
|
|
150
168
|
)
|
|
151
169
|
fig.add_trace(
|
|
152
170
|
go.Bar(
|
|
153
|
-
x=["Benchmark"],
|
|
154
|
-
|
|
155
|
-
|
|
171
|
+
x=["Benchmark"],
|
|
172
|
+
y=[centroid_counts["Benchmark"]],
|
|
173
|
+
text=[f"{centroid_counts['Benchmark']}"],
|
|
174
|
+
textposition="auto",
|
|
175
|
+
marker_color="#a4490e",
|
|
176
|
+
marker_line_color="black",
|
|
177
|
+
marker_line_width=1,
|
|
156
178
|
name=f"Benchmark ({percentages['Benchmark']:.2f}%)",
|
|
157
179
|
),
|
|
158
|
-
row=1,
|
|
180
|
+
row=1,
|
|
181
|
+
col=1,
|
|
159
182
|
)
|
|
160
183
|
|
|
161
184
|
for i, label in enumerate(third_raster_labels):
|
|
162
185
|
fig.add_trace(
|
|
163
186
|
go.Bar(
|
|
164
|
-
x=[label],
|
|
165
|
-
|
|
187
|
+
x=[label],
|
|
188
|
+
y=[third_raster_counts[i]],
|
|
189
|
+
text=[f"{third_raster_counts[i]}"],
|
|
190
|
+
textposition="auto",
|
|
166
191
|
marker_color=["#ff5733", "#ffc300", "#28a745"][i],
|
|
167
|
-
marker_line_color="black",
|
|
192
|
+
marker_line_color="black",
|
|
193
|
+
marker_line_width=1,
|
|
168
194
|
name=f"{label} ({percentages[label]:.2f}%)",
|
|
169
195
|
),
|
|
170
|
-
row=1,
|
|
196
|
+
row=1,
|
|
197
|
+
col=2,
|
|
171
198
|
)
|
|
172
199
|
|
|
173
200
|
fig.update_layout(
|
|
174
201
|
title="Flooded Building Counts",
|
|
175
202
|
xaxis_title="Inundation Surface",
|
|
176
203
|
yaxis_title="Flooded Building Counts",
|
|
177
|
-
width=1100,
|
|
178
|
-
|
|
179
|
-
|
|
204
|
+
width=1100,
|
|
205
|
+
height=400,
|
|
206
|
+
plot_bgcolor="rgba(0,0,0,0)",
|
|
207
|
+
paper_bgcolor="rgba(0,0,0,0)",
|
|
208
|
+
showlegend=True,
|
|
209
|
+
font=dict(family="Arial", size=18, color="black"),
|
|
180
210
|
)
|
|
181
211
|
fig.show()
|
|
182
212
|
|
|
183
|
-
# Seaborn for static PNG
|
|
184
|
-
df_left = pd.DataFrame(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
213
|
+
# Seaborn for static PNG
|
|
214
|
+
df_left = pd.DataFrame(
|
|
215
|
+
{
|
|
216
|
+
"Category": ["Candidate", "Benchmark"],
|
|
217
|
+
"Count": [centroid_counts["Candidate"], centroid_counts["Benchmark"]],
|
|
218
|
+
}
|
|
219
|
+
)
|
|
220
|
+
df_right = pd.DataFrame(
|
|
221
|
+
{
|
|
222
|
+
"Category": third_raster_labels,
|
|
223
|
+
"Count": third_raster_counts,
|
|
224
|
+
}
|
|
225
|
+
)
|
|
192
226
|
|
|
193
227
|
sns.set_theme(style="whitegrid")
|
|
194
|
-
|
|
228
|
+
|
|
229
|
+
fig_sb = plt.figure(figsize=(10, 3), constrained_layout=True)
|
|
230
|
+
gs = gridspec.GridSpec(1, 3, figure=fig_sb, width_ratios=[1, 1, 0.4])
|
|
231
|
+
|
|
232
|
+
ax0 = fig_sb.add_subplot(gs[0, 0])
|
|
233
|
+
ax1 = fig_sb.add_subplot(gs[0, 1])
|
|
234
|
+
ax_leg = fig_sb.add_subplot(gs[0, 2])
|
|
235
|
+
ax_leg.axis("off")
|
|
195
236
|
|
|
196
237
|
def style_axes(ax, title_text, xlab, show_ylabel: bool):
|
|
197
|
-
|
|
198
|
-
ax.
|
|
199
|
-
ax.set_xlabel(xlab, fontsize=14, color="black")
|
|
238
|
+
ax.set_title(title_text, fontsize=14, pad=15)
|
|
239
|
+
ax.set_xlabel(xlab, fontsize=13, color="black")
|
|
200
240
|
if show_ylabel:
|
|
201
|
-
ax.set_ylabel("Flooded Building Counts", fontsize=
|
|
241
|
+
ax.set_ylabel("Flooded Building Counts", fontsize=13, color="black")
|
|
202
242
|
else:
|
|
203
243
|
ax.set_ylabel("")
|
|
204
244
|
|
|
205
|
-
# Thicker black left/bottom spines
|
|
206
245
|
for spine in ("left", "bottom"):
|
|
207
246
|
ax.spines[spine].set_linewidth(1.5)
|
|
208
247
|
ax.spines[spine].set_color("black")
|
|
209
248
|
|
|
210
249
|
sns.despine(ax=ax, right=True, top=True)
|
|
211
|
-
ax.tick_params(axis="x", labelsize=
|
|
212
|
-
ax.tick_params(axis="y", labelsize=
|
|
250
|
+
ax.tick_params(axis="x", labelsize=11, colors="black")
|
|
251
|
+
ax.tick_params(axis="y", labelsize=11, colors="black")
|
|
213
252
|
|
|
214
253
|
# Left panel
|
|
215
|
-
|
|
216
|
-
sns.barplot(data=df_left, x="Category", y="Count", ax=ax0,
|
|
217
|
-
|
|
218
|
-
style_axes(ax0, "Building Counts on Different FIMs", "Inundation Surface", show_ylabel=True)
|
|
254
|
+
colors_left = ["#1c83eb", "#a4490e"]
|
|
255
|
+
sns.barplot(data=df_left, x="Category", y="Count", ax=ax0, palette=colors_left)
|
|
256
|
+
style_axes(ax0, "Building Counts on Different FIMs", "Inundation Surface", True)
|
|
219
257
|
for c in ax0.containers:
|
|
220
|
-
ax0.bar_label(
|
|
258
|
+
ax0.bar_label(
|
|
259
|
+
c, fmt="%.0f", label_type="edge", padding=3, fontsize=12, color="black"
|
|
260
|
+
)
|
|
221
261
|
|
|
222
262
|
# Right panel
|
|
223
|
-
|
|
224
|
-
sns.barplot(data=df_right, x="Category", y="Count", ax=ax1,
|
|
225
|
-
|
|
226
|
-
style_axes(ax1, "Contingency Flooded Building Counts", "Category", show_ylabel=False)
|
|
263
|
+
colors_right = ["#ff5733", "#ffc300", "#28a745"]
|
|
264
|
+
sns.barplot(data=df_right, x="Category", y="Count", ax=ax1, palette=colors_right)
|
|
265
|
+
style_axes(ax1, "Contingency Flooded Building Counts", "Category", False)
|
|
227
266
|
for c in ax1.containers:
|
|
228
|
-
ax1.bar_label(
|
|
267
|
+
ax1.bar_label(
|
|
268
|
+
c, fmt="%.0f", label_type="edge", padding=3, fontsize=12, color="black"
|
|
269
|
+
)
|
|
229
270
|
|
|
271
|
+
# Combined legend
|
|
272
|
+
all_labels = ["Candidate", "Benchmark"] + third_raster_labels
|
|
273
|
+
all_colors = colors_left + colors_right
|
|
274
|
+
legend_handles = [
|
|
275
|
+
plt.Line2D(
|
|
276
|
+
[0],
|
|
277
|
+
[0],
|
|
278
|
+
marker="s",
|
|
279
|
+
color="w",
|
|
280
|
+
markerfacecolor=all_colors[i],
|
|
281
|
+
markersize=12,
|
|
282
|
+
label=f"{all_labels[i]} ({percentages[all_labels[i]]:.2f}%)",
|
|
283
|
+
)
|
|
284
|
+
for i in range(len(all_labels))
|
|
285
|
+
]
|
|
286
|
+
ax_leg.legend(handles=legend_handles, fontsize=12, loc="center left", frameon=True)
|
|
230
287
|
plot_dir = os.path.join(save_dir, "FinalPlots")
|
|
231
288
|
os.makedirs(plot_dir, exist_ok=True)
|
|
232
289
|
output_path = os.path.join(plot_dir, f"BuildingCounts_{basename}.png")
|
|
@@ -236,8 +293,6 @@ def GetFloodedBuildingCountInfo(
|
|
|
236
293
|
print(f"PNG were saved in : {output_path}")
|
|
237
294
|
|
|
238
295
|
|
|
239
|
-
|
|
240
|
-
|
|
241
296
|
def process_TIFF(
|
|
242
297
|
tif_files, contingency_files, building_footprint, boundary, method_path
|
|
243
298
|
):
|
|
@@ -12,19 +12,21 @@ def PlotMetrics(csv_path, method_path):
|
|
|
12
12
|
|
|
13
13
|
# Keep only the desired metrics
|
|
14
14
|
metrics = metrics_df.loc[
|
|
15
|
-
metrics_df["Metrics"].isin(
|
|
16
|
-
"CSI_values", "POD_values", "Acc_values", "Prec_values", "F1_values"
|
|
17
|
-
|
|
15
|
+
metrics_df["Metrics"].isin(
|
|
16
|
+
["CSI_values", "POD_values", "Acc_values", "Prec_values", "F1_values"]
|
|
17
|
+
)
|
|
18
18
|
].copy()
|
|
19
19
|
|
|
20
20
|
# Rename for presentation
|
|
21
|
-
metrics["Metrics"] = metrics["Metrics"].replace(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
metrics["Metrics"] = metrics["Metrics"].replace(
|
|
22
|
+
{
|
|
23
|
+
"CSI_values": "CSI",
|
|
24
|
+
"POD_values": "POD",
|
|
25
|
+
"Acc_values": "Accuracy",
|
|
26
|
+
"Prec_values": "Precision",
|
|
27
|
+
"F1_values": "F1 Score",
|
|
28
|
+
}
|
|
29
|
+
)
|
|
28
30
|
|
|
29
31
|
value_columns = metrics.select_dtypes(include="number").columns
|
|
30
32
|
|
|
@@ -44,7 +46,7 @@ def PlotMetrics(csv_path, method_path):
|
|
|
44
46
|
color="Metrics",
|
|
45
47
|
orientation="h",
|
|
46
48
|
color_discrete_sequence=px.colors.qualitative.Set2,
|
|
47
|
-
title=f"Performance Metrics"
|
|
49
|
+
title=f"Performance Metrics",
|
|
48
50
|
)
|
|
49
51
|
fig_plotly.update_traces(texttemplate="%{text:.2f}", textposition="outside")
|
|
50
52
|
fig_plotly.update_layout(
|
|
@@ -67,34 +69,36 @@ def PlotMetrics(csv_path, method_path):
|
|
|
67
69
|
data=metrics,
|
|
68
70
|
x=value_column,
|
|
69
71
|
y="Metrics",
|
|
70
|
-
hue="Metrics",
|
|
72
|
+
hue="Metrics",
|
|
71
73
|
palette="Set2",
|
|
72
74
|
ax=ax,
|
|
73
75
|
dodge=False,
|
|
74
|
-
legend=False
|
|
76
|
+
legend=False,
|
|
75
77
|
)
|
|
76
78
|
|
|
77
79
|
# Annotate bars
|
|
78
80
|
for container in ax.containers:
|
|
79
|
-
ax.bar_label(container, fmt=
|
|
81
|
+
ax.bar_label(container, fmt="%.2f", label_type="edge", fontsize=14)
|
|
80
82
|
|
|
81
83
|
# Styling
|
|
82
84
|
ax.set_title("Performance Metrics", fontsize=16)
|
|
83
|
-
ax.set_xlabel("Score", fontsize=16, color="black")
|
|
85
|
+
ax.set_xlabel("Score", fontsize=16, color="black") # just bigger, not bold
|
|
84
86
|
ax.set_ylabel("Metrics", fontsize=16, color="black")
|
|
85
87
|
|
|
86
|
-
ax.set_xticks([i/10 for i in range(0, 11, 2)])
|
|
87
|
-
ax.set_xticklabels(
|
|
88
|
+
ax.set_xticks([i / 10 for i in range(0, 11, 2)])
|
|
89
|
+
ax.set_xticklabels(
|
|
90
|
+
[f"{i/10:.1f}" for i in range(0, 11, 2)], fontsize=14, color="black"
|
|
91
|
+
)
|
|
88
92
|
|
|
89
93
|
# Increase y-tick label font size
|
|
90
94
|
ax.tick_params(axis="y", labelsize=12, colors="black")
|
|
91
95
|
ax.tick_params(axis="x", labelsize=14, colors="black")
|
|
92
96
|
|
|
93
97
|
# Force spines black + thicker
|
|
94
|
-
ax.spines[
|
|
95
|
-
ax.spines[
|
|
96
|
-
ax.spines[
|
|
97
|
-
ax.spines[
|
|
98
|
+
ax.spines["left"].set_linewidth(1.5)
|
|
99
|
+
ax.spines["bottom"].set_linewidth(1.5)
|
|
100
|
+
ax.spines["left"].set_color("black")
|
|
101
|
+
ax.spines["bottom"].set_color("black")
|
|
98
102
|
|
|
99
103
|
sns.despine(right=True, top=True)
|
|
100
104
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fimeval
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.56
|
|
4
4
|
Summary: A Framework for Automatic Evaluation of Flood Inundation Mapping Predictions Evaluation
|
|
5
5
|
Author: Surface Dynamics Modeling Lab
|
|
6
6
|
Author-email: Supath Dhital <sdhital@crimson.ua.edu>, Dipshika Devi <ddevi@ua.edu>
|
|
@@ -3,12 +3,10 @@ from pathlib import Path
|
|
|
3
3
|
|
|
4
4
|
Main_dir = (
|
|
5
5
|
# "../docs/sampledata"
|
|
6
|
-
"/Users/supath/Downloads/MSResearch/FIMpef/fimpef/docs/sampledata"
|
|
7
6
|
)
|
|
8
7
|
PWD_dir = "./path/to/PWB"
|
|
9
8
|
output_dir = (
|
|
10
9
|
# "./path/to/output" # This is the output directory where the results will be saved
|
|
11
|
-
"/Users/supath/Downloads/MSResearch/FIMpef/fimpef/docs/output"
|
|
12
10
|
)
|
|
13
11
|
target_crs = "EPSG:5070" # Target CRS for reprojecting the FIMs, need to be in EPSG code of Projected CRS
|
|
14
12
|
target_resolution = 10 # This will be in meters, if it passes the FIMS will be resampled to this resolution else, it will find the coarser resolution among all FIMS for this case and use that to resample!
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|