fimeval 0.1.53__py3-none-any.whl → 0.1.54__py3-none-any.whl

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.
@@ -20,7 +20,6 @@ def Changeintogpkg(input_path, output_dir, layer_name):
20
20
  gdf.to_file(output_gpkg, driver="GPKG")
21
21
  return output_gpkg
22
22
 
23
-
24
23
  def GetFloodedBuildingCountInfo(
25
24
  building_fp_path,
26
25
  study_area_path,
@@ -31,7 +30,6 @@ def GetFloodedBuildingCountInfo(
31
30
  basename,
32
31
  ):
33
32
  output_dir = os.path.dirname(building_fp_path)
34
-
35
33
  building_fp_gpkg = Changeintogpkg(
36
34
  building_fp_path, output_dir, "building_footprint"
37
35
  )
@@ -42,7 +40,6 @@ def GetFloodedBuildingCountInfo(
42
40
  with rasterio.open(raster1_path) as src:
43
41
  target_crs = str(src.crs)
44
42
 
45
- # Reproject all GeoDataFrames to the target CRS
46
43
  if building_gdf.crs != target_crs:
47
44
  building_gdf = building_gdf.to_crs(target_crs)
48
45
  print("reproject building_gdf")
@@ -55,43 +52,32 @@ def GetFloodedBuildingCountInfo(
55
52
  clipped_buildings["centroid"] = clipped_buildings.geometry.centroid
56
53
 
57
54
  centroid_counts = {
58
- "Benchmark": 0,
59
- "Candidate": 0,
60
55
  "False Positive": 0,
61
56
  "False Negative": 0,
62
57
  "True Positive": 0,
63
58
  }
64
59
 
65
- def count_centroids_in_raster(raster_path, label):
60
+ # Count centroids in the contingency map
61
+ def count_centroids_in_contingency(raster_path):
66
62
  with rasterio.open(raster_path) as src:
67
63
  raster_data = src.read(1)
68
- transform = src.transform
69
-
70
64
  for centroid in clipped_buildings["centroid"]:
71
65
  row, col = src.index(centroid.x, centroid.y)
72
66
  if 0 <= row < raster_data.shape[0] and 0 <= col < raster_data.shape[1]:
73
67
  pixel_value = raster_data[row, col]
74
- if label in ["Benchmark", "Candidate"]:
75
- if pixel_value == 2: # False Positive
76
- centroid_counts[label] += 1
77
- else:
78
- if pixel_value == 2:
79
- centroid_counts["False Positive"] += 1
80
- elif pixel_value == 3:
81
- centroid_counts["False Negative"] += 1
82
- elif pixel_value == 4:
83
- centroid_counts["True Positive"] += 1
68
+ if pixel_value == 2:
69
+ centroid_counts["False Positive"] += 1
70
+ elif pixel_value == 3:
71
+ centroid_counts["False Negative"] += 1
72
+ elif pixel_value == 4:
73
+ centroid_counts["True Positive"] += 1
84
74
 
85
- if "bm" in str(raster1_path).lower():
86
- count_centroids_in_raster(raster1_path, "Benchmark")
87
- count_centroids_in_raster(raster2_path, "Candidate")
75
+ count_centroids_in_contingency(contingency_map)
88
76
 
89
- elif "candidate" in str(raster2_path).lower():
90
- count_centroids_in_raster(raster1_path, "Candidate")
91
- count_centroids_in_raster(raster2_path, "Benchmark")
77
+ # Calculate Candidate and Benchmark counts from the contingency map counts
78
+ centroid_counts["Candidate"] = centroid_counts["True Positive"] + centroid_counts["False Positive"]
79
+ centroid_counts["Benchmark"] = centroid_counts["True Positive"] + centroid_counts["False Negative"]
92
80
 
93
- if "contingency" in str(contingency_map).lower():
94
- count_centroids_in_raster(contingency_map, "Contingency")
95
81
 
96
82
  total_buildings = len(clipped_buildings)
97
83
  percentages = {
@@ -107,10 +93,14 @@ def GetFloodedBuildingCountInfo(
107
93
  FAR = FP / (TP + FP) if (TP + FP) > 0 else 0
108
94
  POD = TP / (TP + FN) if (TP + FN) > 0 else 0
109
95
 
110
- BDR = (
111
- centroid_counts["Candidate"] - centroid_counts["Benchmark"]
112
- ) / centroid_counts["Benchmark"]
113
-
96
+ if centroid_counts["Benchmark"] > 0:
97
+ BDR = (
98
+ (centroid_counts["Candidate"] - centroid_counts["Benchmark"])
99
+ / centroid_counts["Benchmark"]
100
+ )
101
+ else:
102
+ BDR = 0
103
+
114
104
  counts_data = {
115
105
  "Category": [
116
106
  "Candidate",
@@ -290,15 +280,19 @@ def detect_shapefile(folder):
290
280
  def ensure_pyspark(version: str | None = "3.5.4") -> None:
291
281
  """Install pyspark at runtime via `uv pip` into this env (no-op if present)."""
292
282
  import importlib, shutil, subprocess, sys, re
283
+
293
284
  try:
294
285
  import importlib.util
286
+
295
287
  if importlib.util.find_spec("pyspark"):
296
288
  return
297
289
  except Exception:
298
290
  pass
299
291
  uv = shutil.which("uv")
300
292
  if not uv:
301
- raise RuntimeError("`uv` not found on PATH. Please install uv or add it to PATH.")
293
+ raise RuntimeError(
294
+ "`uv` not found on PATH. Please install uv or add it to PATH."
295
+ )
302
296
  if version is None:
303
297
  spec = "pyspark"
304
298
  else:
@@ -307,7 +301,6 @@ def ensure_pyspark(version: str | None = "3.5.4") -> None:
307
301
  subprocess.check_call([uv, "pip", "install", "--python", sys.executable, spec])
308
302
 
309
303
 
310
-
311
304
  def EvaluationWithBuildingFootprint(
312
305
  main_dir,
313
306
  method_name,
@@ -338,11 +331,11 @@ def EvaluationWithBuildingFootprint(
338
331
  boundary = detect_shapefile(main_dir)
339
332
 
340
333
  building_footprintMS = building_footprint
341
-
334
+
342
335
  if building_footprintMS is None:
343
336
  ensure_pyspark()
344
337
  from .microsoftBF import BuildingFootprintwithISO
345
-
338
+
346
339
  out_dir = os.path.join(method_path, "BuildingFootprint")
347
340
  if not os.path.exists(out_dir):
348
341
  os.makedirs(out_dir)
@@ -398,11 +391,11 @@ def EvaluationWithBuildingFootprint(
398
391
  boundary = detect_shapefile(os.path.join(main_dir, folder))
399
392
 
400
393
  building_footprintMS = building_footprint
401
-
394
+
402
395
  if building_footprintMS is None:
403
396
  ensure_pyspark()
404
397
  from .microsoftBF import BuildingFootprintwithISO
405
-
398
+
406
399
  out_dir = os.path.join(method_path, "BuildingFootprint")
407
400
  if not os.path.exists(out_dir):
408
401
  os.makedirs(out_dir)
@@ -18,6 +18,7 @@ warnings.filterwarnings("ignore")
18
18
  # Authenticate and initialize Earth Engine
19
19
  ee.Authenticate()
20
20
 
21
+
21
22
  # %%
22
23
  def split_into_tiles(boundary, tile_size=0.1):
23
24
  bounds = boundary.total_bounds
@@ -31,24 +31,35 @@ def is_writable(path):
31
31
 
32
32
  def fix_permissions(path):
33
33
  path = Path(path).resolve()
34
- script_path = Path(__file__).parent / "fix_permissions.sh"
35
-
36
- if not script_path.exists():
37
- raise FileNotFoundError(f"Shell script not found: {script_path}")
38
34
 
39
35
  if is_writable(path):
40
36
  return
41
37
 
38
+ uname = platform.system()
39
+
42
40
  try:
43
- result = subprocess.run(
44
- ["bash", str(script_path), str(path)],
45
- check=True,
46
- capture_output=True,
47
- text=True,
48
- )
49
- print(result.stdout)
41
+ if uname in ["Darwin", "Linux"]:
42
+ subprocess.run(
43
+ ["chmod", "-R", "u+rwX", str(path)],
44
+ check=True,
45
+ capture_output=True,
46
+ text=True,
47
+ )
48
+ print(f"Permissions granted for user (u+rwX): {path}")
49
+
50
+ elif "MINGW" in uname or "MSYS" in uname or "CYGWIN" in uname:
51
+ subprocess.run(
52
+ ["icacls", str(path), "/grant", "Everyone:F", "/T"],
53
+ check=True,
54
+ capture_output=True,
55
+ text=True,
56
+ )
57
+ print(f"Permissions granted for working folder: {path}")
58
+
59
+ else:
60
+ print(f"Unsupported OS: {uname}")
50
61
  except subprocess.CalledProcessError as e:
51
- print(f"Shell script failed:\n{e.stderr}")
62
+ print(f"Failed to fix permissions for {path}:\n{e.stderr}")
52
63
 
53
64
 
54
65
  # Function for the evalution of the model