Skip to content

Commit 0a21f91

Browse files
committed
Fix linter/mypy warnings
1 parent 29bd930 commit 0a21f91

7 files changed

Lines changed: 105 additions & 48 deletions

File tree

deltap/global_code_residents_pixel.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def calc_persistence_value(
5050

5151
def process_delta_p(
5252
current: yg.YirgacheffeLayer,
53-
scenario: yg.YirgacheffeLayer,
53+
scenario: yg.YirgacheffeLayer | float,
5454
current_aoh: float,
5555
historic_aoh: float,
5656
exponent: str | float
@@ -88,6 +88,7 @@ def global_code_residents_pixel_ae(
8888
sys.exit(f"Failed to open current layer {current_aohs_path / filename}")
8989

9090
try:
91+
scenario: yg.YirgacheffeLayer | float
9192
scenario, _ = open_layer(scenario_aohs_path / filename)
9293
except FileNotFoundError:
9394
# If there is a current but now scenario file it's because the species went extinct under the scenario
@@ -143,8 +144,8 @@ def global_code_residents_pixel_ae(
143144
non_breeding_scenario_path = scenario_aohs_path / nonbreeding_filename
144145
breeding_scenario_path = scenario_aohs_path / breeding_filename
145146
else:
146-
non_breeding_scenario_path = "nan"
147-
breeding_scenario_path = "nan"
147+
non_breeding_scenario_path = Path("nan") # nan path is the sentinel from csv inputs
148+
breeding_scenario_path = Path("nan")
148149

149150
try:
150151
current_breeding, current_aoh_breeding = open_layer(current_aohs_path / breeding_filename)
@@ -155,11 +156,13 @@ def global_code_residents_pixel_ae(
155156
except FileNotFoundError:
156157
sys.exit(f"Failed to open current non breeding {current_aohs_path / nonbreeding_filename}")
157158
try:
159+
scenario_breeding: yg.YirgacheffeLayer | float
158160
scenario_breeding, _ = open_layer(breeding_scenario_path)
159161
except FileNotFoundError:
160162
# If there is a current but now scenario file it's because the species went extinct under the scenario
161163
scenario_breeding = 0.0
162164
try:
165+
scenario_non_breeding: yg.YirgacheffeLayer | float
163166
scenario_non_breeding, _ = open_layer(non_breeding_scenario_path)
164167
except FileNotFoundError:
165168
# If there is a current but now scenario file it's because the species went extinct under the scenario

local/merge_global_habitat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def merge_global_habitat(
2727
local_layer.set_window_for_union(global_layer.area)
2828
cleared = local_layer.nan_to_num()
2929
combined = yg.where(cleared != 0, local_layer, global_layer)
30-
ctx = alive_bar(manual=True, title=str(lcc)) if show_progress else nullcontext()
30+
ctx = alive_bar(manual=True) if show_progress else nullcontext()
3131
with ctx as bar:
3232
combined.to_geotiff(output_layer_path, callback=bar, parallelism=True)
3333

prepare_layers/make_diff_map.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import argparse
2+
from contextlib import nullcontext
23
from pathlib import Path
34

45
import yirgacheffe as yg
6+
from alive_progress import alive_bar # type: ignore
7+
from snakemake_argparse_bridge import snakemake_compatible # type: ignore
58

69
POSSIBLE_HABITAT_CLASSES = [100, 200, 300, 400, 500, 600, 700, 800, 900,
710
1000, 1100, 1200, 1300, 1400, 1401, 1402, 1403, 1404,
@@ -21,15 +24,27 @@ def make_diff_map(
2124

2225
if not current_habitat_filename.exists() and not scenario_habitat_filename.exists():
2326
continue
24-
current_layer = yg.read_raster(current_habitat_filename) if current_habitat_filename.exists() else yg.constant(0.0)
25-
scenario_layer = yg.read_raster(scenario_habitat_filename) if scenario_habitat_filename.exists() else yg.constant(0.0)
27+
current_layer = yg.read_raster(current_habitat_filename) if current_habitat_filename.exists() \
28+
else yg.constant(0.0)
29+
scenario_layer = yg.read_raster(scenario_habitat_filename) if scenario_habitat_filename.exists() \
30+
else yg.constant(0.0)
2631
habitat_diff = current_layer != scenario_layer
2732
layers.append(habitat_diff)
33+
2834
diff = yg.any(layers)
2935
area = yg.area_raster(diff.map_projection)
3036
scaled_diff = diff * area
31-
scaled_diff.to_geotiff(output_path, parallelism=parallelism)
3237

38+
ctx = alive_bar(manual=True) if show_progress else nullcontext()
39+
with ctx as bar:
40+
scaled_diff.to_geotiff(output_path, callback=bar, parallelism=parallelism)
41+
42+
@snakemake_compatible(mapping={
43+
"current_path": "input.current",
44+
"scenario_path": "params.scenario",
45+
"parallelism": "threads",
46+
"output_path": "output[0]",
47+
})
3348
def main() -> None:
3449
parser = argparse.ArgumentParser(description="Generate an area difference map.")
3550
parser.add_argument(
@@ -51,7 +66,7 @@ def main() -> None:
5166
type=Path,
5267
help='Path where final map should be stored',
5368
required=True,
54-
dest='results_path',
69+
dest='output_path',
5570
)
5671
parser.add_argument(
5772
'-j',
@@ -74,7 +89,7 @@ def main() -> None:
7489
make_diff_map(
7590
args.current_path,
7691
args.scenario_path,
77-
args.results_path,
92+
args.output_path,
7893
args.parallelism,
7994
args.show_progress,
8095
)

prepare_layers/make_food_current_map.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ def make_food_current_map(
346346
os.makedirs(output_path.parent, exist_ok=True)
347347

348348
lcc_list = get_lcc_list(current_lvl1_path)
349-
result_queues: dict[int,multiprocessing.queues.Queue] = { lcc: multiprocessing.Queue(maxsize=10) for lcc in lcc_list}
349+
result_queues: dict[int,multiprocessing.queues.Queue] = {
350+
lcc: multiprocessing.Queue(maxsize=10) for lcc in lcc_list
351+
}
350352

351353
assembly_processes = [
352354
Process(target=assemble_map, args=(

tests/test_food_layer.py

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11

22
import numpy as np
33
import pytest
4-
import yirgacheffe as yg
54

6-
from prepare_layers.make_food_current_map import TileInfo, process_tile, balance_crop_and_pasture_differences, \
5+
from prepare_layers.make_food_current_map import balance_crop_and_pasture_differences, \
76
CROP_CODE, PASTURE_CODE, remove_land_cover, add_land_cover
87

9-
@pytest.mark.parametrize("initial_crop_diff,initial_pasture_diff,expected_crop_diff,expected_pasture_diff", [
10-
(0.0, 0.0, 0.0, 0.0),
11-
(0.8, 0.0, 0.8, 0.0),
12-
(-0.8, 0.0, -0.8, 0.0),
13-
(0.0, 0.8, 0.0, 0.8),
14-
(0.0, -0.8, 0.0, -0.8),
15-
(0.4, 0.2, 0.4, 0.2),
16-
(-0.4, -0.2, -0.4, -0.2),
17-
])
8+
@pytest.mark.parametrize(
9+
[
10+
"initial_crop_diff",
11+
"initial_pasture_diff",
12+
"expected_crop_diff",
13+
"expected_pasture_diff"
14+
],
15+
[
16+
(0.0, 0.0, 0.0, 0.0),
17+
(0.8, 0.0, 0.8, 0.0),
18+
(-0.8, 0.0, -0.8, 0.0),
19+
(0.0, 0.8, 0.0, 0.8),
20+
(0.0, -0.8, 0.0, -0.8),
21+
(0.4, 0.2, 0.4, 0.2),
22+
(-0.4, -0.2, -0.4, -0.2),
23+
]
24+
)
1825
def test_balance_not_needed(
1926
initial_crop_diff: float,
2027
initial_pasture_diff: float,
@@ -24,30 +31,35 @@ def test_balance_not_needed(
2431
result_crop_diff, result_pasture_diff = balance_crop_and_pasture_differences(
2532
initial_crop_diff,
2633
initial_pasture_diff,
27-
dict(),
34+
{},
2835
)
2936
assert expected_crop_diff == result_crop_diff
3037
assert expected_pasture_diff == result_pasture_diff
3138

3239

33-
def test_one_sided_balance() -> None:
40+
def test_brokend_balance() -> None:
41+
# Testing that we spot if we've said to remove land where there isn't any
3442
lcc_data_map = {
3543
CROP_CODE: np.zeros((10, 10)),
3644
PASTURE_CODE: np.zeros((10, 10)),
3745
}
38-
result_crop_diff, result_pasture_diff = balance_crop_and_pasture_differences(
39-
0.5,
40-
-0.1,
41-
lcc_data_map,
42-
)
43-
# assert expected_crop_diff == result_crop_diff
44-
# assert expected_pasture_diff == result_pasture_diff
45-
# assert (lcc_data_map[CROP_CODE] == crop_cell_value).all()
46-
# assert (lcc_data_map[PASTURE_CODE] == pasture_cell_value).all()
46+
with pytest.raises(ValueError):
47+
_ = balance_crop_and_pasture_differences(
48+
0.5,
49+
-0.1,
50+
lcc_data_map,
51+
)
4752

4853

4954
@pytest.mark.parametrize(
50-
"initial_crop_diff,initial_pasture_diff,expected_crop_diff,expected_pasture_diff,crop_cell_value,pasture_cell_value",
55+
[
56+
"initial_crop_diff",
57+
"initial_pasture_diff",
58+
"expected_crop_diff",
59+
"expected_pasture_diff",
60+
"crop_cell_value",
61+
"pasture_cell_value"
62+
],
5163
[
5264
(0.25, -0.5, 0.0, -0.25, 0.25, 0.75),
5365
]
@@ -77,7 +89,14 @@ def test_simple_balance_transfer(
7789

7890

7991
@pytest.mark.parametrize(
80-
"initial_crop_diff,initial_pasture_diff,expected_crop_diff,expected_pasture_diff,crop_cell_value,pasture_cell_value",
92+
[
93+
"initial_crop_diff",
94+
"initial_pasture_diff",
95+
"expected_crop_diff",
96+
"expected_pasture_diff",
97+
"crop_cell_value",
98+
"pasture_cell_value"
99+
],
81100
[
82101
(0.25, -0.5, 0.0, -0.25, 0.5, 0.5),
83102
(0.5, -0.25, 0.25, 0.0, 0.5, 0.5),
@@ -110,9 +129,16 @@ def test_simple_half_balance_transfer(
110129
assert (expected_pasture_map == lcc_data_map[PASTURE_CODE]).all()
111130

112131

113-
@pytest.mark.parametrize("crop_diff,expected_crop_cell,expected_other_cell", [
114-
(-0.5, 0.5, 0.5),
115-
])
132+
@pytest.mark.parametrize(
133+
[
134+
"crop_diff",
135+
"expected_crop_cell",
136+
"expected_other_cell",
137+
],
138+
[
139+
(-0.5, 0.5, 0.5),
140+
]
141+
)
116142
def test_remove_land_simple(
117143
crop_diff: float,
118144
expected_crop_cell: float,
@@ -138,13 +164,22 @@ def test_remove_land_simple(
138164
assert (expected_other_map == lcc_data_map[1]).all()
139165

140166

141-
@pytest.mark.parametrize("crop_diff,pnv_value,expected_crop_cell,expected_other_1_cell,expected_other_2_cell", [
142-
(-0.5, 1, 0.0, 1.0, 0.0),
143-
(-0.75, 1, 0.0, 1.0, 0.0), # too much
144-
(-0.25, 1, 0.5, 0.5, 0.0),
145-
(-0.5, 2, 0.0, 0.0, 1.0),
146-
(-0.25, 2, 0.5, 0.0, 0.5),
147-
])
167+
@pytest.mark.parametrize(
168+
[
169+
"crop_diff",
170+
"pnv_value",
171+
"expected_crop_cell",
172+
"expected_other_1_cell",
173+
"expected_other_2_cell",
174+
],
175+
[
176+
(-0.5, 1, 0.0, 1.0, 0.0),
177+
(-0.75, 1, 0.0, 1.0, 0.0), # too much
178+
(-0.25, 1, 0.5, 0.5, 0.0),
179+
(-0.5, 2, 0.0, 0.0, 1.0),
180+
(-0.25, 2, 0.5, 0.0, 0.5),
181+
]
182+
)
148183
def test_remove_land_less_simple(
149184
crop_diff: float,
150185
pnv_value: int,
@@ -189,7 +224,6 @@ def test_add_land_simple(
189224
1: np.ones((10, 10)),
190225
CROP_CODE: np.zeros((10, 10)),
191226
}
192-
pnv_data = np.full((10, 10), 1)
193227

194228
add_land_cover(
195229
CROP_CODE,
@@ -217,7 +251,6 @@ def test_add_land_avoid_excluded(
217251
PASTURE_CODE: np.array([[i % 2] * 10 for i in range(10)]).astype(float),
218252
CROP_CODE: np.zeros((10, 10)),
219253
}
220-
pnv_data = np.full((10, 10), 1)
221254

222255
add_land_cover(
223256
CROP_CODE,

utils/footprint_of_humanity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def absolute(
2424
merge1 = pd.merge(current_cleaned, pnv_cleaned, on=["id_no", "season"], suffixes=["_current", "_pnv"])
2525
merge2 = pd.merge(merge1, scenario, on=["id_no", "season"], how="left", indicator=True)
2626
merged = merge2[["id_no", "season", "class_name", "aoh_total_current", "aoh_total_pnv", "aoh_total", "_merge"]].copy()
27-
merged.aoh_total = merged.aoh_total.fillna(0)
27+
merged["aoh_total"] = merged.aoh_total.fillna(0)
2828
merged.rename(columns={"aoh_total": "aoh_total_scenario"}, inplace=True)
2929

3030
merged["current_persistence"] = (merged.aoh_total_current / merged.aoh_total_pnv) ** 0.25

utils/raster_sum.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import argparse
2-
import os
32
import resource
43
from pathlib import Path
54

65
import yirgacheffe as yg
76
from alive_progress import alive_bar # type: ignore
7+
from snakemake_argparse_bridge import snakemake_compatible # type: ignore
88

99
def raster_sum(
1010
images_dir: Path,
@@ -20,6 +20,10 @@ def raster_sum(
2020
with alive_bar(manual=True) as bar:
2121
total.to_geotiff(output_filename, callback=bar, parallelism=True)
2222

23+
@snakemake_compatible(mapping={
24+
"rasters_directory": "input.rasters",
25+
"output_filename": "output[0]",
26+
})
2327
def main() -> None:
2428
parser = argparse.ArgumentParser(description="Sums many rasters into a single raster")
2529
parser.add_argument(

0 commit comments

Comments
 (0)