openforis-whisp 0.1.0a8__py3-none-any.whl → 2.0.0a1__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.
- openforis_whisp/__init__.py +6 -3
- openforis_whisp/data_conversion.py +36 -13
- openforis_whisp/datasets.py +787 -90
- openforis_whisp/logger.py +38 -2
- openforis_whisp/parameters/config_runtime.py +4 -7
- openforis_whisp/parameters/lookup_context_and_metadata.csv +13 -13
- openforis_whisp/parameters/lookup_gee_datasets.csv +202 -155
- openforis_whisp/reformat.py +245 -96
- openforis_whisp/risk.py +472 -24
- openforis_whisp/stats.py +271 -70
- openforis_whisp-2.0.0a1.dist-info/METADATA +381 -0
- openforis_whisp-2.0.0a1.dist-info/RECORD +17 -0
- openforis_whisp-0.1.0a8.dist-info/METADATA +0 -188
- openforis_whisp-0.1.0a8.dist-info/RECORD +0 -17
- {openforis_whisp-0.1.0a8.dist-info → openforis_whisp-2.0.0a1.dist-info}/LICENSE +0 -0
- {openforis_whisp-0.1.0a8.dist-info → openforis_whisp-2.0.0a1.dist-info}/WHEEL +0 -0
openforis_whisp/datasets.py
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# This file contains python code for the Google Earth Engine datasets used in the Whisp pacakge.
|
|
2
|
+
|
|
3
|
+
# If you are running a bespoke analysis including your own datasets see also the main README.md file.
|
|
4
|
+
|
|
5
|
+
# Key aspects to include in the code for each function are:
|
|
6
|
+
# a) a suffix of ' _prep' and
|
|
7
|
+
# b) a prefix of "nXX_" if it is national/sub-national dataset (where XX is replaced by that country code), or a prefix of 'g_' if it covers more than one country.
|
|
8
|
+
# c) a name for your image, defined by ".rename('add_your_image_name_here')". This becomes the column header in the output table.
|
|
9
|
+
|
|
10
|
+
# NB for all the above you will need to be running the package in editable mode for these local changes to take effect.
|
|
11
|
+
# Editable mode runs the package locally and thus changes to any files are reflected immediately.
|
|
12
|
+
|
|
1
13
|
import ee
|
|
2
14
|
|
|
3
15
|
# ee.Authenticate()
|
|
@@ -32,7 +44,7 @@ def get_logger(name):
|
|
|
32
44
|
|
|
33
45
|
|
|
34
46
|
# ESA_TC_2020
|
|
35
|
-
def
|
|
47
|
+
def g_esa_worldcover_trees_prep():
|
|
36
48
|
esa_worldcover_2020_raw = ee.Image("ESA/WorldCover/v100/2020")
|
|
37
49
|
esa_worldcover_trees_2020 = esa_worldcover_2020_raw.eq(95).Or(
|
|
38
50
|
esa_worldcover_2020_raw.eq(10)
|
|
@@ -41,25 +53,27 @@ def esa_worldcover_trees_prep():
|
|
|
41
53
|
|
|
42
54
|
|
|
43
55
|
# EUFO_2020
|
|
44
|
-
def
|
|
56
|
+
def g_jrc_gfc_2020_prep():
|
|
45
57
|
jrc_gfc2020_raw = ee.ImageCollection("JRC/GFC2020/V2")
|
|
46
58
|
return jrc_gfc2020_raw.mosaic().rename("EUFO_2020")
|
|
47
59
|
|
|
48
60
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
## removing JAXA product due to repeat errors of commission being noted by users, compared to other datasets
|
|
62
|
+
|
|
63
|
+
# # JAXA_FNF_2020
|
|
64
|
+
# def g_jaxa_forest_prep():
|
|
65
|
+
# jaxa_forest_non_forest_raw = ee.ImageCollection("JAXA/ALOS/PALSAR/YEARLY/FNF4")
|
|
66
|
+
# jaxa_forest_non_forest_2020 = (
|
|
67
|
+
# jaxa_forest_non_forest_raw.filterDate("2020-01-01", "2020-12-31")
|
|
68
|
+
# .select("fnf")
|
|
69
|
+
# .mosaic()
|
|
70
|
+
# )
|
|
71
|
+
# return jaxa_forest_non_forest_2020.lte(2).rename("JAXA_FNF_2020")
|
|
58
72
|
|
|
59
73
|
|
|
60
74
|
# GFC_TC_2020
|
|
61
|
-
def
|
|
62
|
-
gfc = ee.Image("UMD/hansen/
|
|
75
|
+
def g_glad_gfc_10pc_prep():
|
|
76
|
+
gfc = ee.Image("UMD/hansen/global_forest_change_2024_v1_12")
|
|
63
77
|
gfc_treecover2000 = gfc.select(["treecover2000"])
|
|
64
78
|
gfc_loss2001_2020 = gfc.select(["lossyear"]).lte(20)
|
|
65
79
|
gfc_treecover2020 = gfc_treecover2000.where(gfc_loss2001_2020.eq(1), 0)
|
|
@@ -67,14 +81,14 @@ def glad_gfc_10pc_prep():
|
|
|
67
81
|
|
|
68
82
|
|
|
69
83
|
# GLAD_Primary
|
|
70
|
-
def
|
|
84
|
+
def g_glad_pht_prep():
|
|
71
85
|
primary_ht_forests2001_raw = ee.ImageCollection(
|
|
72
86
|
"UMD/GLAD/PRIMARY_HUMID_TROPICAL_FORESTS/v1"
|
|
73
87
|
)
|
|
74
88
|
primary_ht_forests2001 = (
|
|
75
89
|
primary_ht_forests2001_raw.select("Primary_HT_forests").mosaic().selfMask()
|
|
76
90
|
)
|
|
77
|
-
gfc = ee.Image("UMD/hansen/
|
|
91
|
+
gfc = ee.Image("UMD/hansen/global_forest_change_2024_v1_12")
|
|
78
92
|
gfc_loss2001_2020 = gfc.select(["lossyear"]).lte(20)
|
|
79
93
|
return primary_ht_forests2001.where(gfc_loss2001_2020.eq(1), 0).rename(
|
|
80
94
|
"GLAD_Primary"
|
|
@@ -82,9 +96,9 @@ def glad_pht_prep():
|
|
|
82
96
|
|
|
83
97
|
|
|
84
98
|
# TMF_undist (undistrubed forest in 2020)
|
|
85
|
-
def
|
|
99
|
+
def g_jrc_tmf_undisturbed_prep():
|
|
86
100
|
TMF_undist_2020 = (
|
|
87
|
-
ee.ImageCollection("projects/JRC/TMF/
|
|
101
|
+
ee.ImageCollection("projects/JRC/TMF/v1_2024/AnnualChanges")
|
|
88
102
|
.select("Dec2020")
|
|
89
103
|
.mosaic()
|
|
90
104
|
.eq(1)
|
|
@@ -93,7 +107,7 @@ def jrc_tmf_undisturbed_prep():
|
|
|
93
107
|
|
|
94
108
|
|
|
95
109
|
# Forest Persistence FDaP
|
|
96
|
-
def
|
|
110
|
+
def g_fdap_forest_prep():
|
|
97
111
|
fdap_forest_raw = ee.Image(
|
|
98
112
|
"projects/forestdatapartnership/assets/community_forests/ForestPersistence_2020"
|
|
99
113
|
)
|
|
@@ -101,16 +115,67 @@ def fdap_forest_prep():
|
|
|
101
115
|
return fdap_forest.rename("Forest_FDaP")
|
|
102
116
|
|
|
103
117
|
|
|
104
|
-
|
|
118
|
+
#########################primary forest
|
|
119
|
+
# EUFO JRC Global forest type - primary
|
|
120
|
+
def g_gft_primary_prep():
|
|
121
|
+
gft_raw = ee.ImageCollection("JRC/GFC2020_subtypes/V0").mosaic()
|
|
122
|
+
gft_primary = gft_raw.eq(10)
|
|
123
|
+
return gft_primary.rename("GFT_primary")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# Intact Forest Landscape 2020
|
|
127
|
+
def g_ifl_2020_prep():
|
|
128
|
+
IFL_2020 = ee.Image("users/potapovpeter/IFL_2020")
|
|
129
|
+
return IFL_2020.rename("IFL_2020")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# European Primary Forest Dataset
|
|
133
|
+
def g_epfd_prep():
|
|
134
|
+
EPFD = ee.FeatureCollection("HU_BERLIN/EPFD/V2/polygons")
|
|
135
|
+
EPFD_binary = ee.Image().paint(EPFD, 1)
|
|
136
|
+
return EPFD_binary.rename("European_Primary_Forest")
|
|
105
137
|
|
|
106
138
|
|
|
139
|
+
# EUFO JRC Global forest type - naturally regenerating planted/plantation forests
|
|
140
|
+
def g_gft_nat_reg_prep():
|
|
141
|
+
gft_raw = ee.ImageCollection("JRC/GFC2020_subtypes/V0").mosaic()
|
|
142
|
+
gft_nat_reg = gft_raw.eq(1)
|
|
143
|
+
return gft_nat_reg.rename("GFT_naturally_regenerating")
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
#########################planted and plantation forests
|
|
147
|
+
|
|
148
|
+
# EUFO JRC Global forest type - planted/plantation forests
|
|
149
|
+
def g_gft_plantation_prep():
|
|
150
|
+
gft_raw = ee.ImageCollection("JRC/GFC2020_subtypes/V0").mosaic()
|
|
151
|
+
gft_plantation = gft_raw.eq(20)
|
|
152
|
+
return gft_plantation.rename("GFT_planted_plantation")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def g_iiasa_planted_prep():
|
|
156
|
+
iiasa = ee.Image("projects/sat-io/open-datasets/GFM/FML_v3-2")
|
|
157
|
+
iiasa_PL = iiasa.eq(31).Or(iiasa.eq(32))
|
|
158
|
+
return iiasa_PL.rename("IIASA_planted_plantation")
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
#########################TMF regrowth in 2023
|
|
162
|
+
def g_tmf_regrowth_prep():
|
|
163
|
+
# Load the TMF Degradation annual product
|
|
164
|
+
TMF_AC = ee.ImageCollection("projects/JRC/TMF/v1_2024/AnnualChanges").mosaic()
|
|
165
|
+
TMF_AC_2023 = TMF_AC.select("Dec2023")
|
|
166
|
+
Regrowth_TMF = TMF_AC_2023.eq(4)
|
|
167
|
+
return Regrowth_TMF.rename("TMF_regrowth_2023")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
############tree crops
|
|
171
|
+
|
|
107
172
|
# TMF_plant (plantations in 2020)
|
|
108
|
-
def
|
|
173
|
+
def g_jrc_tmf_plantation_prep():
|
|
109
174
|
transition = ee.ImageCollection(
|
|
110
|
-
"projects/JRC/TMF/
|
|
175
|
+
"projects/JRC/TMF/v1_2024/TransitionMap_Subtypes"
|
|
111
176
|
).mosaic()
|
|
112
177
|
deforestation_year = ee.ImageCollection(
|
|
113
|
-
"projects/JRC/TMF/
|
|
178
|
+
"projects/JRC/TMF/v1_2024/DeforestationYear"
|
|
114
179
|
).mosaic()
|
|
115
180
|
plantation = (transition.gte(81)).And(transition.lte(86))
|
|
116
181
|
plantation_2020 = plantation.where(
|
|
@@ -121,7 +186,7 @@ def jrc_tmf_plantation_prep():
|
|
|
121
186
|
|
|
122
187
|
# # Oil_palm_Descals
|
|
123
188
|
# NB updated to Descals et al 2024 paper (as opposed to Descals et al 2021 paper)
|
|
124
|
-
def
|
|
189
|
+
def g_creaf_descals_palm_prep():
|
|
125
190
|
# Load the Global Oil Palm Year of Plantation image and mosaic it
|
|
126
191
|
img = (
|
|
127
192
|
ee.ImageCollection(
|
|
@@ -138,72 +203,127 @@ def creaf_descals_palm_prep():
|
|
|
138
203
|
plantation_2020 = oil_palm_plantation_year.lte(2020).selfMask()
|
|
139
204
|
return plantation_2020.rename("Oil_palm_Descals")
|
|
140
205
|
|
|
141
|
-
# Calculate the year of plantation
|
|
142
|
-
oil_palm_plantation_year = img.divide(365).add(1970).floor().lte(2020)
|
|
143
|
-
|
|
144
|
-
# Create a mask for plantations in the year 2020 or earlier
|
|
145
|
-
plantation_2020 = oil_palm_plantation_year.lte(2020).selfMask()
|
|
146
|
-
return plantation_2020.rename("Oil_palm_Descals")
|
|
147
|
-
|
|
148
206
|
|
|
149
207
|
# Cocoa_ETH
|
|
150
|
-
def
|
|
208
|
+
def g_eth_kalischek_cocoa_prep():
|
|
151
209
|
return ee.Image("projects/ee-nk-cocoa/assets/cocoa_map_threshold_065").rename(
|
|
152
210
|
"Cocoa_ETH"
|
|
153
211
|
)
|
|
154
212
|
|
|
155
213
|
|
|
214
|
+
# fdap datasets
|
|
215
|
+
|
|
216
|
+
# Thresholds and model info here https://github.com/google/forest-data-partnership/blob/main/models/README.md
|
|
217
|
+
|
|
156
218
|
# Oil Palm FDaP
|
|
157
|
-
def
|
|
219
|
+
def g_fdap_palm_prep():
|
|
158
220
|
fdap_palm2020_model_raw = ee.ImageCollection(
|
|
159
|
-
"projects/forestdatapartnership/assets/palm/
|
|
221
|
+
"projects/forestdatapartnership/assets/palm/model_2025a"
|
|
160
222
|
)
|
|
161
223
|
fdap_palm = (
|
|
162
224
|
fdap_palm2020_model_raw.filterDate("2020-01-01", "2020-12-31")
|
|
163
225
|
.mosaic()
|
|
164
|
-
.gt(0.
|
|
226
|
+
.gt(0.88) # Precision and recall ~78% at 0.88 threshold.
|
|
165
227
|
)
|
|
166
228
|
return fdap_palm.rename("Oil_palm_FDaP")
|
|
167
229
|
|
|
168
230
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
"projects/forestdatapartnership/assets/rubber/model_2024a"
|
|
231
|
+
def g_fdap_palm_2023_prep():
|
|
232
|
+
fdap_palm2020_model_raw = ee.ImageCollection(
|
|
233
|
+
"projects/forestdatapartnership/assets/palm/model_2025a"
|
|
173
234
|
)
|
|
174
|
-
|
|
175
|
-
|
|
235
|
+
fdap_palm = (
|
|
236
|
+
fdap_palm2020_model_raw.filterDate("2023-01-01", "2023-12-31")
|
|
176
237
|
.mosaic()
|
|
177
|
-
.gt(0.
|
|
238
|
+
.gt(0.88) # Precision and recall ~78% at 0.88 threshold.
|
|
178
239
|
)
|
|
179
|
-
return
|
|
240
|
+
return fdap_palm.rename("Oil_palm_2023_FDaP")
|
|
180
241
|
|
|
181
242
|
|
|
182
243
|
# Cocoa FDaP
|
|
183
|
-
def
|
|
244
|
+
def g_fdap_cocoa_prep():
|
|
184
245
|
fdap_cocoa2020_model_raw = ee.ImageCollection(
|
|
185
|
-
"projects/forestdatapartnership/assets/cocoa/
|
|
246
|
+
"projects/forestdatapartnership/assets/cocoa/model_2025a"
|
|
186
247
|
)
|
|
187
248
|
fdap_cocoa = (
|
|
188
249
|
fdap_cocoa2020_model_raw.filterDate("2020-01-01", "2020-12-31")
|
|
189
250
|
.mosaic()
|
|
190
|
-
.gt(0.
|
|
251
|
+
.gt(0.96) # Precision and recall ~87% 0.96 threshold.
|
|
191
252
|
)
|
|
192
253
|
return fdap_cocoa.rename("Cocoa_FDaP")
|
|
193
254
|
|
|
194
255
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
.
|
|
201
|
-
.
|
|
202
|
-
|
|
256
|
+
def g_fdap_cocoa_2023_prep():
|
|
257
|
+
fdap_cocoa2020_model_raw = ee.ImageCollection(
|
|
258
|
+
"projects/forestdatapartnership/assets/cocoa/model_2025a"
|
|
259
|
+
)
|
|
260
|
+
fdap_cocoa = (
|
|
261
|
+
fdap_cocoa2020_model_raw.filterDate("2023-01-01", "2023-12-31")
|
|
262
|
+
.mosaic()
|
|
263
|
+
.gt(0.96) # Precision and recall ~87% 0.96 threshold.
|
|
264
|
+
)
|
|
265
|
+
return fdap_cocoa.rename("Cocoa_2023_FDaP")
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# Rubber FDaP
|
|
269
|
+
def g_fdap_rubber_prep():
|
|
270
|
+
fdap_rubber2020_model_raw = ee.ImageCollection(
|
|
271
|
+
"projects/forestdatapartnership/assets/rubber/model_2025a"
|
|
272
|
+
)
|
|
273
|
+
fdap_rubber = (
|
|
274
|
+
fdap_rubber2020_model_raw.filterDate("2020-01-01", "2020-12-31")
|
|
275
|
+
.mosaic()
|
|
276
|
+
.gt(0.59) # Precision and recall ~80% 0.59 threshold.
|
|
277
|
+
)
|
|
278
|
+
return fdap_rubber.rename("Rubber_FDaP")
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def g_fdap_rubber_2023_prep():
|
|
282
|
+
fdap_rubber2020_model_raw = ee.ImageCollection(
|
|
283
|
+
"projects/forestdatapartnership/assets/rubber/model_2025a"
|
|
284
|
+
)
|
|
285
|
+
fdap_rubber = (
|
|
286
|
+
fdap_rubber2020_model_raw.filterDate("2023-01-01", "2023-12-31")
|
|
287
|
+
.mosaic()
|
|
288
|
+
.gt(0.93) # Threshold for Rubber
|
|
289
|
+
)
|
|
290
|
+
return fdap_rubber.rename("Rubber_2023_FDaP")
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
# # Coffee FDaP
|
|
294
|
+
def g_fdap_coffee_2020_prep():
|
|
295
|
+
# Load the coffee model for 2020
|
|
296
|
+
collection = ee.ImageCollection(
|
|
297
|
+
"projects/forestdatapartnership/assets/coffee/model_2025a"
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# Filter the collection for the year 2020 and create a binary mask
|
|
301
|
+
coffee_2020 = (
|
|
302
|
+
collection.filterDate("2020-01-01", "2020-12-31")
|
|
303
|
+
.mosaic()
|
|
304
|
+
.gt(0.99) # Precision and recall ~54% 0.99 threshold.
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
return coffee_2020.rename("Coffee_FDaP")
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def g_fdap_coffee_2023_prep():
|
|
311
|
+
# Load the coffee model for 2020
|
|
312
|
+
collection = ee.ImageCollection(
|
|
313
|
+
"projects/forestdatapartnership/assets/coffee/model_2025a"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
# Filter the collection for the year 2023 and create a binary mask
|
|
317
|
+
coffee_2023 = (
|
|
318
|
+
collection.filterDate("2023-01-01", "2023-12-31")
|
|
319
|
+
.mosaic()
|
|
320
|
+
.gt(0.99) # Precision and recall ~54% 0.99 threshold.
|
|
321
|
+
)
|
|
322
|
+
return coffee_2023.rename("Coffee_FDaP_2023")
|
|
203
323
|
|
|
204
324
|
|
|
205
325
|
# Rubber_RBGE - from Royal Botanical Gardens of Edinburgh (RBGE) NB for 2021
|
|
206
|
-
def
|
|
326
|
+
def g_rbge_rubber_prep():
|
|
207
327
|
return (
|
|
208
328
|
ee.Image(
|
|
209
329
|
"users/wangyxtina/MapRubberPaper/rRubber10m202122_perc1585DifESAdist5pxPF"
|
|
@@ -213,10 +333,71 @@ def rbge_rubber_prep():
|
|
|
213
333
|
)
|
|
214
334
|
|
|
215
335
|
|
|
336
|
+
# soy 2020 South America
|
|
337
|
+
def g_soy_song_2020_prep():
|
|
338
|
+
return ee.Image("projects/glad/soy_annual_SA/2020").unmask().rename("Soy_Song_2020")
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
##############
|
|
342
|
+
# ESRI 2023
|
|
343
|
+
|
|
344
|
+
# ESRI 2023 - Tree Cover
|
|
345
|
+
def g_esri_2023_tc_prep():
|
|
346
|
+
esri_lulc10_raw = ee.ImageCollection(
|
|
347
|
+
"projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS"
|
|
348
|
+
)
|
|
349
|
+
esri_lulc10_TC = (
|
|
350
|
+
esri_lulc10_raw.filterDate("2023-01-01", "2023-12-31").mosaic().eq(2)
|
|
351
|
+
)
|
|
352
|
+
return esri_lulc10_TC.rename("ESRI_2023_TC")
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
# ESRI 2023 - Crop
|
|
356
|
+
def g_esri_2023_crop_prep():
|
|
357
|
+
esri_lulc10_raw = ee.ImageCollection(
|
|
358
|
+
"projects/sat-io/open-datasets/landcover/ESRI_Global-LULC_10m_TS"
|
|
359
|
+
)
|
|
360
|
+
esri_lulc10_crop = (
|
|
361
|
+
esri_lulc10_raw.filterDate("2023-01-01", "2023-12-31").mosaic().eq(5)
|
|
362
|
+
)
|
|
363
|
+
return esri_lulc10_crop.rename("ESRI_2023_crop")
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
# GLC_FCS30D 2022
|
|
367
|
+
|
|
368
|
+
# GLC_FCS30D Tree Cover
|
|
369
|
+
# forest classes + swamp + mangrove / what to do with shrubland?
|
|
370
|
+
def g_glc_fcs30d_tc_2022_prep():
|
|
371
|
+
GLC_FCS30D = (
|
|
372
|
+
ee.ImageCollection("projects/sat-io/open-datasets/GLC-FCS30D/annual")
|
|
373
|
+
.mosaic()
|
|
374
|
+
.select(22)
|
|
375
|
+
)
|
|
376
|
+
GLC_FCS30D_TC = (
|
|
377
|
+
(GLC_FCS30D.gte(51))
|
|
378
|
+
.And(GLC_FCS30D.lte(92))
|
|
379
|
+
.Or(GLC_FCS30D.eq(181))
|
|
380
|
+
.Or(GLC_FCS30D.eq(185))
|
|
381
|
+
)
|
|
382
|
+
return GLC_FCS30D_TC.rename("GLC_FCS30D_TC_2022")
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
# GLC_FCS30D crop
|
|
386
|
+
# 10 Rainfed cropland; 11 Herbaceous cover; 12 Tree or shrub cover (Orchard); 20 Irrigated cropland
|
|
387
|
+
def g_glc_fcs30d_crop_2022_prep():
|
|
388
|
+
GLC_FCS30D = (
|
|
389
|
+
ee.ImageCollection("projects/sat-io/open-datasets/GLC-FCS30D/annual")
|
|
390
|
+
.mosaic()
|
|
391
|
+
.select(22)
|
|
392
|
+
)
|
|
393
|
+
GLC_FCS30D_crop = GLC_FCS30D.gte(10).And(GLC_FCS30D.lte(20))
|
|
394
|
+
return GLC_FCS30D_crop.rename("GLC_FCS30D_crop_2022")
|
|
395
|
+
|
|
396
|
+
|
|
216
397
|
#### disturbances by year
|
|
217
398
|
|
|
218
399
|
# RADD_year_2019 to RADD_year_< current year >
|
|
219
|
-
def
|
|
400
|
+
def g_radd_year_prep():
|
|
220
401
|
from datetime import datetime
|
|
221
402
|
|
|
222
403
|
radd = ee.ImageCollection("projects/radar-wur/raddalert/v1")
|
|
@@ -254,12 +435,12 @@ def radd_year_prep():
|
|
|
254
435
|
|
|
255
436
|
|
|
256
437
|
# TMF_def_2000 to TMF_def_2023
|
|
257
|
-
def
|
|
438
|
+
def g_tmf_def_per_year_prep():
|
|
258
439
|
# Load the TMF Deforestation annual product
|
|
259
|
-
tmf_def = ee.ImageCollection("projects/JRC/TMF/
|
|
440
|
+
tmf_def = ee.ImageCollection("projects/JRC/TMF/v1_2024/DeforestationYear").mosaic()
|
|
260
441
|
img_stack = None
|
|
261
442
|
# Generate an image based on GFC with one band of forest tree loss per year from 2001 to 2022
|
|
262
|
-
for i in range(0,
|
|
443
|
+
for i in range(0, 24 + 1):
|
|
263
444
|
tmf_def_year = tmf_def.eq(2000 + i).rename("TMF_def_" + str(2000 + i))
|
|
264
445
|
if img_stack is None:
|
|
265
446
|
img_stack = tmf_def_year
|
|
@@ -269,12 +450,12 @@ def tmf_def_per_year_prep():
|
|
|
269
450
|
|
|
270
451
|
|
|
271
452
|
# TMF_deg_2000 to TMF_deg_2023
|
|
272
|
-
def
|
|
453
|
+
def g_tmf_deg_per_year_prep():
|
|
273
454
|
# Load the TMF Degradation annual product
|
|
274
|
-
tmf_def = ee.ImageCollection("projects/JRC/TMF/
|
|
455
|
+
tmf_def = ee.ImageCollection("projects/JRC/TMF/v1_2024/DegradationYear").mosaic()
|
|
275
456
|
img_stack = None
|
|
276
457
|
# Generate an image based on GFC with one band of forest tree loss per year from 2001 to 2022
|
|
277
|
-
for i in range(0,
|
|
458
|
+
for i in range(0, 24 + 1):
|
|
278
459
|
tmf_def_year = tmf_def.eq(2000 + i).rename("TMF_deg_" + str(2000 + i))
|
|
279
460
|
if img_stack is None:
|
|
280
461
|
img_stack = tmf_def_year
|
|
@@ -284,12 +465,12 @@ def tmf_deg_per_year_prep():
|
|
|
284
465
|
|
|
285
466
|
|
|
286
467
|
# GFC_loss_year_2001 to GFC_loss_year_2023 (correct for version 11)
|
|
287
|
-
def
|
|
468
|
+
def g_glad_gfc_loss_per_year_prep():
|
|
288
469
|
# Load the Global Forest Change dataset
|
|
289
|
-
gfc = ee.Image("UMD/hansen/
|
|
470
|
+
gfc = ee.Image("UMD/hansen/global_forest_change_2024_v1_12")
|
|
290
471
|
img_stack = None
|
|
291
472
|
# Generate an image based on GFC with one band of forest tree loss per year from 2001 to 2022
|
|
292
|
-
for i in range(1,
|
|
473
|
+
for i in range(1, 24 + 1):
|
|
293
474
|
gfc_loss_year = (
|
|
294
475
|
gfc.select(["lossyear"]).eq(i).And(gfc.select(["treecover2000"]).gt(10))
|
|
295
476
|
)
|
|
@@ -302,7 +483,7 @@ def glad_gfc_loss_per_year_prep():
|
|
|
302
483
|
|
|
303
484
|
|
|
304
485
|
# MODIS_fire_2000 to MODIS_fire_< current year >
|
|
305
|
-
def
|
|
486
|
+
def g_modis_fire_prep():
|
|
306
487
|
modis_fire = ee.ImageCollection("MODIS/061/MCD64A1")
|
|
307
488
|
start_year = 2000
|
|
308
489
|
|
|
@@ -329,7 +510,7 @@ def modis_fire_prep():
|
|
|
329
510
|
|
|
330
511
|
|
|
331
512
|
# ESA_fire_2000 to ESA_fire_2020
|
|
332
|
-
def
|
|
513
|
+
def g_esa_fire_prep():
|
|
333
514
|
esa_fire = ee.ImageCollection("ESA/CCI/FireCCI/5_1")
|
|
334
515
|
start_year = 2001
|
|
335
516
|
|
|
@@ -446,7 +627,7 @@ def esa_fire_prep():
|
|
|
446
627
|
#### disturbances combined (split into before and after 2020)
|
|
447
628
|
|
|
448
629
|
# RADD_after_2020
|
|
449
|
-
def
|
|
630
|
+
def g_radd_after_2020_prep():
|
|
450
631
|
from datetime import datetime
|
|
451
632
|
|
|
452
633
|
radd = ee.ImageCollection("projects/radar-wur/raddalert/v1")
|
|
@@ -471,7 +652,7 @@ def radd_after_2020_prep():
|
|
|
471
652
|
|
|
472
653
|
|
|
473
654
|
# RADD_before_2020
|
|
474
|
-
def
|
|
655
|
+
def g_radd_before_2020_prep():
|
|
475
656
|
from datetime import datetime
|
|
476
657
|
|
|
477
658
|
radd = ee.ImageCollection("projects/radar-wur/raddalert/v1")
|
|
@@ -517,33 +698,33 @@ def radd_before_2020_prep():
|
|
|
517
698
|
|
|
518
699
|
|
|
519
700
|
# TMF_deg_before_2020
|
|
520
|
-
def
|
|
521
|
-
tmf_deg = ee.ImageCollection("projects/JRC/TMF/
|
|
701
|
+
def g_tmf_deg_before_2020_prep():
|
|
702
|
+
tmf_deg = ee.ImageCollection("projects/JRC/TMF/v1_2024/DegradationYear").mosaic()
|
|
522
703
|
return (tmf_deg.lte(2020)).And(tmf_deg.gte(2000)).rename("TMF_deg_before_2020")
|
|
523
704
|
|
|
524
705
|
|
|
525
706
|
# TMF_deg_after_2020
|
|
526
|
-
def
|
|
527
|
-
tmf_deg = ee.ImageCollection("projects/JRC/TMF/
|
|
707
|
+
def g_tmf_deg_after_2020_prep():
|
|
708
|
+
tmf_deg = ee.ImageCollection("projects/JRC/TMF/v1_2024/DegradationYear").mosaic()
|
|
528
709
|
return tmf_deg.gt(2020).rename("TMF_deg_after_2020")
|
|
529
710
|
|
|
530
711
|
|
|
531
712
|
# tmf_def_before_2020
|
|
532
|
-
def
|
|
533
|
-
tmf_def = ee.ImageCollection("projects/JRC/TMF/
|
|
713
|
+
def g_tmf_def_before_2020_prep():
|
|
714
|
+
tmf_def = ee.ImageCollection("projects/JRC/TMF/v1_2024/DeforestationYear").mosaic()
|
|
534
715
|
return (tmf_def.lte(2020)).And(tmf_def.gte(2000)).rename("TMF_def_before_2020")
|
|
535
716
|
|
|
536
717
|
|
|
537
718
|
# tmf_def_after_2020
|
|
538
|
-
def
|
|
539
|
-
tmf_def = ee.ImageCollection("projects/JRC/TMF/
|
|
719
|
+
def g_tmf_def_after_2020_prep():
|
|
720
|
+
tmf_def = ee.ImageCollection("projects/JRC/TMF/v1_2024/DeforestationYear").mosaic()
|
|
540
721
|
return tmf_def.gt(2020).rename("TMF_def_after_2020")
|
|
541
722
|
|
|
542
723
|
|
|
543
724
|
# GFC_loss_before_2020 (loss within 10 percent cover; includes 2020; correct for version 11)
|
|
544
|
-
def
|
|
725
|
+
def g_glad_gfc_loss_before_2020_prep():
|
|
545
726
|
# Load the Global Forest Change dataset
|
|
546
|
-
gfc = ee.Image("UMD/hansen/
|
|
727
|
+
gfc = ee.Image("UMD/hansen/global_forest_change_2024_v1_12")
|
|
547
728
|
gfc_loss = (
|
|
548
729
|
gfc.select(["lossyear"]).lte(20).And(gfc.select(["treecover2000"]).gt(10))
|
|
549
730
|
)
|
|
@@ -551,15 +732,15 @@ def glad_gfc_loss_before_2020_prep():
|
|
|
551
732
|
|
|
552
733
|
|
|
553
734
|
# GFC_loss_after_2020 (loss within 10 percent cover; correct for version 11)
|
|
554
|
-
def
|
|
735
|
+
def g_glad_gfc_loss_after_2020_prep():
|
|
555
736
|
# Load the Global Forest Change dataset
|
|
556
|
-
gfc = ee.Image("UMD/hansen/
|
|
737
|
+
gfc = ee.Image("UMD/hansen/global_forest_change_2024_v1_12")
|
|
557
738
|
gfc_loss = gfc.select(["lossyear"]).gt(20).And(gfc.select(["treecover2000"]).gt(10))
|
|
558
739
|
return gfc_loss.rename("GFC_loss_after_2020")
|
|
559
740
|
|
|
560
741
|
|
|
561
742
|
# MODIS_fire_before_2020
|
|
562
|
-
def
|
|
743
|
+
def g_modis_fire_before_2020_prep():
|
|
563
744
|
modis_fire = ee.ImageCollection("MODIS/061/MCD64A1")
|
|
564
745
|
start_year = 2000
|
|
565
746
|
end_year = 2020
|
|
@@ -575,7 +756,7 @@ def modis_fire_before_2020_prep():
|
|
|
575
756
|
|
|
576
757
|
|
|
577
758
|
# MODIS_fire_after_2020
|
|
578
|
-
def
|
|
759
|
+
def g_modis_fire_after_2020_prep():
|
|
579
760
|
modis_fire = ee.ImageCollection("MODIS/061/MCD64A1")
|
|
580
761
|
start_year = 2021
|
|
581
762
|
end_year = datetime.now().year
|
|
@@ -591,7 +772,7 @@ def modis_fire_after_2020_prep():
|
|
|
591
772
|
|
|
592
773
|
|
|
593
774
|
# ESA_fire_before_2020
|
|
594
|
-
def
|
|
775
|
+
def g_esa_fire_before_2020_prep():
|
|
595
776
|
esa_fire = ee.ImageCollection("ESA/CCI/FireCCI/5_1")
|
|
596
777
|
start_year = 2000
|
|
597
778
|
end_year = 2020
|
|
@@ -606,15 +787,488 @@ def esa_fire_before_2020_prep():
|
|
|
606
787
|
)
|
|
607
788
|
|
|
608
789
|
|
|
609
|
-
|
|
790
|
+
#########################logging concessions
|
|
791
|
+
# http://data.globalforestwatch.org/datasets?q=logging&sort_by=relevance
|
|
792
|
+
def g_logging_concessions_before_2020_prep():
|
|
793
|
+
RCA = ee.FeatureCollection(
|
|
794
|
+
"projects/ee-whisp/assets/logging/RCA_Permis_dExploitation_et_dAmenagement"
|
|
795
|
+
)
|
|
796
|
+
RCA_binary = ee.Image().paint(RCA, 1)
|
|
797
|
+
CMR = ee.FeatureCollection(
|
|
798
|
+
"projects/ee-whisp/assets/logging/Cameroon_Forest_Management_Units"
|
|
799
|
+
)
|
|
800
|
+
CMR_binary = ee.Image().paint(CMR, 1)
|
|
801
|
+
Eq_G = ee.FeatureCollection(
|
|
802
|
+
"projects/ee-whisp/assets/logging/Equatorial_Guinea_logging_concessions"
|
|
803
|
+
)
|
|
804
|
+
Eq_G_binary = ee.Image().paint(Eq_G, 1)
|
|
805
|
+
DRC = ee.FeatureCollection(
|
|
806
|
+
"projects/ee-whisp/assets/logging/DRC_Forest_concession_agreements"
|
|
807
|
+
)
|
|
808
|
+
DRC_binary = ee.Image().paint(DRC, 1)
|
|
809
|
+
Liberia = ee.FeatureCollection(
|
|
810
|
+
"projects/ee-whisp/assets/logging/Liberia_Forest_Management_Contracts"
|
|
811
|
+
)
|
|
812
|
+
Liberia_binary = ee.Image().paint(Liberia, 1)
|
|
813
|
+
RoC = ee.FeatureCollection(
|
|
814
|
+
"projects/ee-whisp/assets/logging/Republic_of_the_Congo_logging_concessions"
|
|
815
|
+
)
|
|
816
|
+
Roc_binary = ee.Image().paint(RoC, 1)
|
|
817
|
+
Sarawak = ee.FeatureCollection(
|
|
818
|
+
"projects/ee-whisp/assets/logging/Sarawak_logging_concessions"
|
|
819
|
+
)
|
|
820
|
+
Sarawak_binary = ee.Image().paint(Sarawak, 1)
|
|
821
|
+
logging_concessions_binary = ee.ImageCollection(
|
|
822
|
+
[
|
|
823
|
+
RCA_binary,
|
|
824
|
+
CMR_binary,
|
|
825
|
+
Eq_G_binary,
|
|
826
|
+
DRC_binary,
|
|
827
|
+
Liberia_binary,
|
|
828
|
+
Roc_binary,
|
|
829
|
+
Sarawak_binary,
|
|
830
|
+
]
|
|
831
|
+
).mosaic()
|
|
832
|
+
|
|
833
|
+
return logging_concessions_binary.rename("GFW_logging_before_2020")
|
|
834
|
+
|
|
835
|
+
|
|
836
|
+
#########################national datasets
|
|
837
|
+
|
|
838
|
+
# nBR Brazil
|
|
839
|
+
|
|
840
|
+
# ### nBR Natural forests in 2020:
|
|
841
|
+
|
|
842
|
+
# %%
|
|
843
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Amazon biome, 2020
|
|
844
|
+
# Subsetting criteria: primary forests (DN=1) and secondary forests (DN=2) // secondary forests are those recovering from deforestation
|
|
845
|
+
# the resulting dataset shows primary and secondary forest cover in 2020 (mostly by August 2020)
|
|
846
|
+
|
|
847
|
+
##########################primary forests###############################################
|
|
848
|
+
def nbr_terraclass_amz20_primary_prep():
|
|
849
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
850
|
+
tcamz20_f = tcamz20.eq(1)
|
|
851
|
+
return tcamz20_f.rename("nBR_INPE_TC_primary_forest_Amazon_2020")
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
# [Official NFMS dataset] Brazilian Forest Service dataset on natural forest cover from PRODES and TerraClass data, base year 2022
|
|
855
|
+
# Subsetting criteria: ano_desmat > 2020 and nom_class = 'Floresta'
|
|
856
|
+
# the resulting datasets show primary forest cover in 2020 for the Pantanal, Caatinga, Atlantic Forest and Pampa biomes.
|
|
857
|
+
# the resulting dataset shows primary and secondary forest cover in 2020 for the Cerrado biome (TerraClass 2020)
|
|
858
|
+
# For the Amazon, best to use Terraclass 2020 directly, because the BFS used TerraClass 2014.
|
|
859
|
+
|
|
860
|
+
# Pantanal
|
|
861
|
+
def nbr_bfs_ptn_f20_prep():
|
|
862
|
+
bfs_fptn20 = ee.FeatureCollection("projects/ee-whisp/assets/NBR/bfs_ptn_2020")
|
|
863
|
+
|
|
864
|
+
bfs_fptn20_binary = ee.Image().paint(bfs_fptn20, 1)
|
|
865
|
+
return bfs_fptn20_binary.rename("nBR_BFS_primary_forest_Pantanal_2020")
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
# Caatinga - filtered with QGIS because the original geodatabase is too large to export as a shapefile (GEE accepted format)
|
|
869
|
+
## couldn't convert it to asset, working on it (Error: Primary geometry of feature '306862' has 2454627 vertices, above the limit of 1000000 vertices. (Error code: 3)
|
|
870
|
+
def nbr_bfs_caat_f20_prep():
|
|
871
|
+
bfs_fcaat20 = ee.FeatureCollection("projects/ee-whisp/assets/NBR/bfs_caat_2020")
|
|
872
|
+
bfs_fcaat20_binary = ee.Image().paint(bfs_fcaat20, 1)
|
|
873
|
+
return bfs_fcaat20_binary.rename("nBR_BFS_primary_forest_Caatinga_2020")
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
# Atlantic Forest - filtered with QGIS because the original geodatabase is too large to export as a shapefile (GEE accepted format)
|
|
877
|
+
def nbr_bfs_atlf_f20_prep():
|
|
878
|
+
bfs_fatlf20 = ee.FeatureCollection("projects/ee-whisp/assets/NBR/bfs_atlf_2020")
|
|
879
|
+
bfs_fatlf20_binary = ee.Image().paint(bfs_fatlf20, 1)
|
|
880
|
+
return bfs_fatlf20_binary.rename("nBR_BFS_primary_forest_AtlanticForest_2020")
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
# Pampa - filtered in QGIS to save some storage space
|
|
884
|
+
def nbr_bfs_pmp_f20_prep():
|
|
885
|
+
bfs_fpmp20 = ee.FeatureCollection("projects/ee-whisp/assets/NBR/bfs_pmp_2020")
|
|
886
|
+
bfs_fpmp20_binary = ee.Image().paint(bfs_fpmp20, 1)
|
|
887
|
+
return bfs_fpmp20_binary.rename("nBR_BFS_primary_forest_Pampa_2020")
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
##########################secondary forests###############################################
|
|
891
|
+
def nbr_terraclass_amz20_secondary_prep():
|
|
892
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
893
|
+
tcamz20_f = tcamz20.eq(2)
|
|
894
|
+
return tcamz20_f.rename("nBR_INPE_TC_secondary_forest_Amazon_2020")
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
# Cerrado - filtered with QGIS because the original geodatabase is too large to export as a shapefile (GEE accepted format)
|
|
898
|
+
def nbr_bfs_cer_f20_prep():
|
|
899
|
+
bfs_fcer20 = ee.FeatureCollection("projects/ee-whisp/assets/NBR/bfs_pmp_2020")
|
|
900
|
+
bfs_fcer20_binary = ee.Image().paint(bfs_fcer20, 1)
|
|
901
|
+
return bfs_fcer20_binary.rename("nBR_BFS_primary&secondary_forest_Cerrado_2020")
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
# %%
|
|
905
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
906
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
907
|
+
# Subsetting criteria: classification_2020 = Forest formation (DN=3), Savanna Formation (DN=4, forest according to BR definition), Mangrove (DN=5), Floodable Forest (DN=6), Wooded Sandbank veg (DN=49)
|
|
908
|
+
# the resulting dataset shows forest cover in 2020, without distinguishing between primary and secondary forests
|
|
909
|
+
def nbr_mapbiomasc9_f20_prep():
|
|
910
|
+
mapbiomasc9_20 = ee.Image(
|
|
911
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
912
|
+
).select("classification_2020")
|
|
913
|
+
mapbiomasc9_20_forest = (
|
|
914
|
+
mapbiomasc9_20.eq(3)
|
|
915
|
+
.Or(mapbiomasc9_20.eq(4))
|
|
916
|
+
.Or(mapbiomasc9_20.eq(5))
|
|
917
|
+
.Or(mapbiomasc9_20.eq(6))
|
|
918
|
+
.Or(mapbiomasc9_20.eq(49))
|
|
919
|
+
)
|
|
920
|
+
return mapbiomasc9_20_forest.rename("nBR_MapBiomas_col9_forest_Brazil_2020")
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
# ### ########################NBR plantation forest in 2020:#######################################
|
|
924
|
+
|
|
925
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Amazon biome, 2020
|
|
926
|
+
# Subsetting criteria: silviculture (DN=9)
|
|
927
|
+
# the resulting dataset shows monospecific commercial plantations, mostly eucalyptus and pinus.
|
|
928
|
+
def nbr_terraclass_amz20_silv_prep():
|
|
929
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
930
|
+
tcamz20_silviculture = tcamz20.eq(9)
|
|
931
|
+
return tcamz20_silviculture.rename("nBR_INPE_TCsilviculture_Amazon_2020")
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Cerrado biome, 2020
|
|
935
|
+
# Subsetting criteria: silviculture (DN=9)
|
|
936
|
+
# the resulting dataset shows monospecific commercial plantations, mostly eucalyptus and pinus.
|
|
937
|
+
def nbr_terraclass_silv_cer20_prep():
|
|
938
|
+
tccer20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_cer_2020")
|
|
939
|
+
tccer20_silviculture = tccer20.eq(9)
|
|
940
|
+
return tccer20_silviculture.rename("nBR_INPE_TCsilviculture_Cerrado_2020")
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
944
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
945
|
+
# Subsetting criteria: 'classification_2020' = Forest plantation (DN=9)
|
|
946
|
+
# the resulting dataset shows forest plantation in 2020
|
|
947
|
+
def nbr_mapbiomasc9_silv20_prep():
|
|
948
|
+
mapbiomasc9_20 = ee.Image(
|
|
949
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
950
|
+
).select("classification_2020")
|
|
951
|
+
mapbiomasc9_20_silviculture = mapbiomasc9_20.eq(9)
|
|
952
|
+
return mapbiomasc9_20_silviculture.rename(
|
|
953
|
+
"nBR_MapBiomas_col9_silviculture_Brazil_2020"
|
|
954
|
+
)
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
################ ### NBR Disturbances before 2020:########################################
|
|
958
|
+
|
|
959
|
+
# [Official NFMS dataset] INPE PRODES data up to 2023
|
|
960
|
+
# Subsetting criteria: DN = [0, 2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60];
|
|
961
|
+
|
|
962
|
+
# the resulting dataset shows deforestation and conversion of OWL and OL up to 2020 (mostly August 2020), including residues (omission errors corrections)
|
|
963
|
+
def nbr_prodes_before_2020_prep():
|
|
964
|
+
prodes = ee.Image("projects/ee-whisp/assets/NBR/prodes_brasil_2023")
|
|
965
|
+
prodes_before_20_dn = [
|
|
966
|
+
0,
|
|
967
|
+
2,
|
|
968
|
+
4,
|
|
969
|
+
6,
|
|
970
|
+
7,
|
|
971
|
+
8,
|
|
972
|
+
9,
|
|
973
|
+
10,
|
|
974
|
+
11,
|
|
975
|
+
12,
|
|
976
|
+
13,
|
|
977
|
+
14,
|
|
978
|
+
15,
|
|
979
|
+
16,
|
|
980
|
+
17,
|
|
981
|
+
18,
|
|
982
|
+
19,
|
|
983
|
+
20,
|
|
984
|
+
50,
|
|
985
|
+
51,
|
|
986
|
+
52,
|
|
987
|
+
53,
|
|
988
|
+
54,
|
|
989
|
+
55,
|
|
990
|
+
56,
|
|
991
|
+
57,
|
|
992
|
+
58,
|
|
993
|
+
59,
|
|
994
|
+
60,
|
|
995
|
+
]
|
|
996
|
+
prodes_before_20_mask = prodes.remap(
|
|
997
|
+
prodes_before_20_dn, [1] * len(prodes_before_20_dn)
|
|
998
|
+
) # .eq(1)
|
|
999
|
+
prodes_before_20 = prodes_before_20_mask.selfMask()
|
|
1000
|
+
return prodes_before_20.rename("nBR_PRODES_deforestation_Brazil_before_2020")
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
## Caution: 1) includes deforestation and conversion of other wooded land and grassland
|
|
1004
|
+
|
|
1005
|
+
# [Official NFMS dataset] INPE.DETER data from 2nd August 2016 up to the 04th of April 2025
|
|
1006
|
+
# Subsetting criteria: forest degradation classes ['CICATRIZ_DE_QUEIMADA', 'CS_DESORDENADO', 'DEGRADACAO'] and view_date until 2020-12-31
|
|
1007
|
+
# 'CS_GEOMETRICO' excluded to align with FREL
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
def nbr_deter_amazon_before_2020_prep():
|
|
1011
|
+
deteramz = ee.FeatureCollection("projects/ee-whisp/assets/NBR/deter_amz_16apr2025")
|
|
1012
|
+
degradation_classes = ["CICATRIZ_DE_QUEIMADA", "CS_DESORDENADO", "DEGRADACAO"]
|
|
1013
|
+
|
|
1014
|
+
# Add a formatted date field based on VIEW_DATE
|
|
1015
|
+
def add_formatted_date(feature):
|
|
1016
|
+
return feature.set("formatted_date", ee.Date(feature.get("VIEW_DATE")))
|
|
1017
|
+
|
|
1018
|
+
deteramz = deteramz.map(add_formatted_date)
|
|
1019
|
+
|
|
1020
|
+
deter_deg = deteramz.filter(
|
|
1021
|
+
ee.Filter.inList("CLASSNAME", degradation_classes)
|
|
1022
|
+
).filter(ee.Filter.lt("formatted_date", ee.Date("2020-12-31")))
|
|
1023
|
+
|
|
1024
|
+
deter_deg_binary = ee.Image().paint(deter_deg, 1)
|
|
1025
|
+
return deter_deg_binary.rename("nBR_DETER_forestdegradation_Amazon_before_2020")
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
################ ### NBR Disturbances after 2020:########################################
|
|
1029
|
+
# [Official NFMS dataset] INPE PRODES data up to 2023
|
|
1030
|
+
# Subsetting criteria: DN = [21, 22, 23, 61, 62, 63];
|
|
1031
|
+
|
|
1032
|
+
# the resulting dataset shows deforestation and conversion of OWL and OL up to 2020 (mostly August 2020), including residues (omission errors corrections)
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
def nbr_prodes_after_2020_prep():
|
|
1036
|
+
prodes = ee.Image("projects/ee-whisp/assets/NBR/prodes_brasil_2023")
|
|
1037
|
+
prodes_after_20_dn = [21, 22, 23, 61, 62, 63]
|
|
1038
|
+
prodes_after_20_mask = prodes.remap(
|
|
1039
|
+
prodes_after_20_dn, [1] * len(prodes_after_20_dn)
|
|
1040
|
+
) # .eq(1)
|
|
1041
|
+
prodes_after_20 = prodes_after_20_mask.selfMask()
|
|
1042
|
+
return prodes_after_20.rename("nBR_PRODES_deforestation_Brazil_after_2020")
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
# %%
|
|
1046
|
+
# [Official NFMS dataset] INPE.DETER data from 2nd August 2016 up to the 04th of April 2025
|
|
1047
|
+
# Subsetting criteria: forest degradation classes ['CICATRIZ_DE_QUEIMADA', 'CS_DESORDENADO', 'DEGRADACAO'] and view_date from 2021-01-01 onward
|
|
1048
|
+
# 'CS_GEOMETRICO' excluded to align with FREL
|
|
1049
|
+
def nbr_deter_amazon_after_2020_prep():
|
|
1050
|
+
deteramz = ee.FeatureCollection("projects/ee-whisp/assets/NBR/deter_amz_16apr2025")
|
|
1051
|
+
degradation_classes = ["CICATRIZ_DE_QUEIMADA", "CS_DESORDENADO", "DEGRADACAO"]
|
|
1052
|
+
|
|
1053
|
+
# Add a formatted date field based on VIEW_DATE
|
|
1054
|
+
def add_formatted_date(feature):
|
|
1055
|
+
return feature.set("formatted_date", ee.Date(feature.get("VIEW_DATE")))
|
|
1056
|
+
|
|
1057
|
+
deteramz = deteramz.map(add_formatted_date)
|
|
1058
|
+
|
|
1059
|
+
deter_deg = deteramz.filter(
|
|
1060
|
+
ee.Filter.inList("CLASSNAME", degradation_classes)
|
|
1061
|
+
).filter(ee.Filter.gt("formatted_date", ee.Date("2021-01-01")))
|
|
1062
|
+
|
|
1063
|
+
deter_deg_binary = ee.Image().paint(deter_deg, 1)
|
|
1064
|
+
return deter_deg_binary.rename("nBR_DETER_forestdegradation_Amazon_after_2020")
|
|
1065
|
+
|
|
1066
|
+
|
|
1067
|
+
# ########################## NBR commodities - permanent/perennial crops in 2020:###############################
|
|
1068
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Amazon biome, 2020
|
|
1069
|
+
# OR [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Cerrado biome, 2020
|
|
1070
|
+
# Subsetting criteria: perennial (DN=12) and semi-perennial (DN=13) crops
|
|
1071
|
+
# the resulting dataset shows perennial and semi-perennial crops in 2020
|
|
1072
|
+
def nbr_terraclass_amz_cer20_pc_prep():
|
|
1073
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
1074
|
+
tcamz20_pc = tcamz20.eq(12).Or(tcamz20.eq(13))
|
|
1075
|
+
tccer20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_cer_2020")
|
|
1076
|
+
tccer20_pc = tccer20.eq(12).Or(tccer20.eq(13))
|
|
1077
|
+
tc_pc = ee.ImageCollection([tcamz20_pc, tccer20_pc]).mosaic()
|
|
1078
|
+
return tc_pc.rename("nBR_INPE_TCamz_cer_perennial_2020")
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1082
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1083
|
+
# Subsetting criteria: 'classification_2020' = coffee (DN=46) <================== COFFEE
|
|
1084
|
+
# the resulting dataset shows coffee area in 2020
|
|
1085
|
+
def nbr_mapbiomasc9_cof_prep():
|
|
1086
|
+
mapbiomasc9_20 = ee.Image(
|
|
1087
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1088
|
+
).select("classification_2020")
|
|
1089
|
+
mapbiomasc9_20_coffee = mapbiomasc9_20.eq(46)
|
|
1090
|
+
return mapbiomasc9_20_coffee.rename("nBR_MapBiomas_col9_coffee_2020")
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1094
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1095
|
+
# Subsetting criteria: 'classification_2020' = palm oil (DN=35) <================= PALM OIL
|
|
1096
|
+
# the resulting dataset shows palm oil area in 2020
|
|
1097
|
+
def nbr_mapbiomasc9_po_prep():
|
|
1098
|
+
mapbiomasc9_20 = ee.Image(
|
|
1099
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1100
|
+
).select("classification_2020")
|
|
1101
|
+
mapbiomasc9_20_palm = mapbiomasc9_20.eq(35)
|
|
1102
|
+
return mapbiomasc9_20_palm.rename("nBR_MapBiomas_col9_palmoil_2020")
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1106
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1107
|
+
# Subsetting criteria: 'classification_2020' = other perennial crops (DN=48)
|
|
1108
|
+
# the resulting dataset shows citrus and perennial crops other than coffee and palm oil in 2020
|
|
1109
|
+
def nbr_mapbiomasc9_pc_prep():
|
|
1110
|
+
mapbiomasc9_20 = ee.Image(
|
|
1111
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1112
|
+
).select("classification_2020")
|
|
1113
|
+
mapbiomasc9_20_pc = mapbiomasc9_20.eq(35).Or(mapbiomasc9_20.eq(46))
|
|
1114
|
+
return mapbiomasc9_20_pc.rename("nBR_MapBiomas_col9_pc_2020")
|
|
1115
|
+
|
|
1116
|
+
|
|
1117
|
+
# ######################## NBR commodities - annual crops in 2020:##############################
|
|
1118
|
+
|
|
1119
|
+
# %%
|
|
1120
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Amazon biome, 2020
|
|
1121
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Cerrado biome, 2020
|
|
1122
|
+
# Subsetting criteria: annual/temporary 1 cycle (DN=14) or more than 1 cycle (DN=15)
|
|
1123
|
+
# the resulting dataset shows temporary crop in 2020
|
|
1124
|
+
def nbr_terraclass_amz_cer20_ac_prep():
|
|
1125
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
1126
|
+
tcamz20_ac = tcamz20.eq(14).Or(tcamz20.eq(15))
|
|
1127
|
+
tccer20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_cer_2020")
|
|
1128
|
+
tccer20_ac = tccer20.eq(14).Or(tccer20.eq(15))
|
|
1129
|
+
tc_ac = ee.ImageCollection([tcamz20_ac, tccer20_ac]).mosaic()
|
|
1130
|
+
return tc_ac.rename("nBR_INPE_TCamz_cer_annual_2020")
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1134
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1135
|
+
# Subsetting criteria: 'classification_2020' = soybean (DN=39) <================== SOY
|
|
1136
|
+
# the resulting dataset shows soybean plantation area in 2020
|
|
1137
|
+
def nbr_mapbiomasc9_soy_prep():
|
|
1138
|
+
mapbiomasc9_20 = ee.Image(
|
|
1139
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1140
|
+
).select("classification_2020")
|
|
1141
|
+
mapbiomasc9_20_soy = mapbiomasc9_20.eq(39)
|
|
1142
|
+
return mapbiomasc9_20_soy.rename("nBR_MapBiomas_col9_soy_2020")
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1146
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1147
|
+
# Subsetting criteria: 'classification_2020' = other temporary crops (DN=41)
|
|
1148
|
+
# Subsetting criteria: 'classification_2020' = sugar cane (DN=20)
|
|
1149
|
+
# Subsetting criteria: 'classification_2020' = rice (DN=40)
|
|
1150
|
+
# Subsetting criteria: 'classification_2020' = cotton (beta version, DN=62)
|
|
1151
|
+
# the resulting dataset shows temporary crop area other than soy, includes sugar cane, rice, and cotton
|
|
1152
|
+
def nbr_mapbiomasc9_ac_prep():
|
|
1153
|
+
mapbiomasc9_20 = ee.Image(
|
|
1154
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1155
|
+
).select("classification_2020")
|
|
1156
|
+
mapbiomasc9_20_ac = (
|
|
1157
|
+
mapbiomasc9_20.eq(41)
|
|
1158
|
+
.Or(mapbiomasc9_20.eq(20))
|
|
1159
|
+
.Or(mapbiomasc9_20.eq(40))
|
|
1160
|
+
.Or(mapbiomasc9_20.eq(62))
|
|
1161
|
+
)
|
|
1162
|
+
return mapbiomasc9_20_ac.rename("nBR_MapBiomas_col9_annual_crops_2020")
|
|
1163
|
+
|
|
1164
|
+
|
|
1165
|
+
# ################################### NBR commodities - pasture/livestock in 2020:##############################
|
|
1166
|
+
|
|
1167
|
+
# %%
|
|
1168
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Amazon biome, 2020
|
|
1169
|
+
# Subsetting criteria: BUSH/SHRUB PASTURE (DN=10) or HERBACEOUS PASTURE (DN=11)
|
|
1170
|
+
|
|
1171
|
+
# the resulting dataset shows 2020 pasture area in the Amazon
|
|
1172
|
+
def nbr_terraclass_amz20_pasture_prep():
|
|
1173
|
+
tcamz20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_amz_2020")
|
|
1174
|
+
tcamz20_pasture = tcamz20.eq(10).Or(tcamz20.eq(11))
|
|
1175
|
+
return tcamz20_pasture.rename("nBR_INPE_TCamz_pasture_2020")
|
|
1176
|
+
|
|
1177
|
+
|
|
1178
|
+
# %%
|
|
1179
|
+
# [Official NFMS dataset] INPE/EMBRAPA TerraClass land use/cover in the Cerrado biome, 2020
|
|
1180
|
+
# Subsetting criteria: PASTURE (DN=11)
|
|
1181
|
+
# the resulting dataset shows 2020 pasture area in the Cerrado
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
def nbr_terraclass_cer20_ac_prep():
|
|
1185
|
+
tccer20 = ee.Image("projects/ee-whisp/assets/NBR/terraclass_cer_2020")
|
|
1186
|
+
tccer20_pasture = tccer20.eq(11)
|
|
1187
|
+
return tccer20_pasture.rename("nBR_INPE_TCcer_pasture_2020")
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
# %%
|
|
1191
|
+
# [non-official dataset by MapBiomas multisector initiative]
|
|
1192
|
+
# land use/cover from 1985 up to 2023, collection 9
|
|
1193
|
+
# Subsetting criteria: 'classification_2020' = pasture (DN=15)
|
|
1194
|
+
# the resulting dataset shows pasture area in 2020 in Brazil
|
|
1195
|
+
def nbr_mapbiomasc9_pasture_prep():
|
|
1196
|
+
mapbiomasc9_20 = ee.Image(
|
|
1197
|
+
"projects/mapbiomas-public/assets/brazil/lulc/collection9/mapbiomas_collection90_integration_v1"
|
|
1198
|
+
).select("classification_2020")
|
|
1199
|
+
mapbiomasc9_20_pasture = mapbiomasc9_20.eq(15)
|
|
1200
|
+
return mapbiomasc9_20_pasture.rename("nBR_MapBiomas_col9_pasture_2020")
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
###################################################################
|
|
1204
|
+
# nCO - Colombia
|
|
1205
|
+
|
|
1206
|
+
|
|
1207
|
+
def nco_ideam_forest_2020_prep():
|
|
1208
|
+
ideam_forest_raw = ee.Image("projects/ee-whisp/assets/nCO/ideam_2020_geo")
|
|
1209
|
+
ideam_forest = ideam_forest_raw.eq(1) # get forest class
|
|
1210
|
+
return ideam_forest.rename("nCO_ideam_forest_2020")
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
def nco_ideam_agroforest_2020_prep():
|
|
1214
|
+
ideam_agroforest_raw = ee.Image("projects/ee-whisp/assets/nCO/ideam_2020_geo_EUFO")
|
|
1215
|
+
ideam_agroforest = ideam_agroforest_raw.eq(4) # get forest class
|
|
1216
|
+
return ideam_agroforest.rename("nCO_ideam_agroforest_2020")
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
# Cocoa_bnetd
|
|
1220
|
+
def nci_ocs2020_prep():
|
|
1221
|
+
return (
|
|
1222
|
+
ee.Image("BNETD/land_cover/v1/2020")
|
|
1223
|
+
.select("classification")
|
|
1224
|
+
.eq(9)
|
|
1225
|
+
.rename("nCI_Cocoa_bnetd")
|
|
1226
|
+
) # cocoa from national land cover map for Côte d'Ivoire
|
|
1227
|
+
|
|
1228
|
+
|
|
1229
|
+
###Combining datasets
|
|
1230
|
+
|
|
1231
|
+
###Combining datasets
|
|
1232
|
+
|
|
1233
|
+
# def combine_datasets():
|
|
1234
|
+
# """Combines datasets into a single multiband image, with fallback if assets are missing."""
|
|
1235
|
+
# img_combined = ee.Image(1).rename(geometry_area_column)
|
|
610
1236
|
|
|
1237
|
+
# # Combine images directly
|
|
1238
|
+
# for img in [func() for func in list_functions()]:
|
|
1239
|
+
# try:
|
|
1240
|
+
# img_combined = img_combined.addBands(img)
|
|
1241
|
+
# except ee.EEException as e:
|
|
1242
|
+
# # logger.error(f"Error adding image: {e}")
|
|
1243
|
+
# print(f"Error adding image: {e}")
|
|
611
1244
|
|
|
612
|
-
|
|
1245
|
+
# try:
|
|
1246
|
+
# # Attempt to print band names to check for errors
|
|
1247
|
+
# print(img_combined.bandNames().getInfo())
|
|
1248
|
+
# except ee.EEException as e:
|
|
1249
|
+
# # logger.error(f"Error printing band names: {e}")
|
|
1250
|
+
# # logger.info("Running code for filtering to only valid datasets due to error in input")
|
|
1251
|
+
# print("using valid datasets filter due to error in input")
|
|
1252
|
+
# # Validate images
|
|
1253
|
+
# images_to_test = [func() for func in list_functions()]
|
|
1254
|
+
# valid_imgs = keep_valid_images(images_to_test) # Validate images
|
|
1255
|
+
|
|
1256
|
+
# # Retry combining images after validation
|
|
1257
|
+
# img_combined = ee.Image(1).rename(geometry_area_column)
|
|
1258
|
+
# for img in valid_imgs:
|
|
1259
|
+
# img_combined = img_combined.addBands(img)
|
|
1260
|
+
|
|
1261
|
+
# img_combined = img_combined.multiply(ee.Image.pixelArea())
|
|
1262
|
+
|
|
1263
|
+
# return img_combined
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
def combine_datasets(national_codes=None):
|
|
613
1267
|
"""Combines datasets into a single multiband image, with fallback if assets are missing."""
|
|
614
1268
|
img_combined = ee.Image(1).rename(geometry_area_column)
|
|
615
1269
|
|
|
616
1270
|
# Combine images directly
|
|
617
|
-
for img in [func() for func in list_functions()]:
|
|
1271
|
+
for img in [func() for func in list_functions(national_codes=national_codes)]:
|
|
618
1272
|
try:
|
|
619
1273
|
img_combined = img_combined.addBands(img)
|
|
620
1274
|
except ee.EEException as e:
|
|
@@ -629,7 +1283,9 @@ def combine_datasets():
|
|
|
629
1283
|
# logger.info("Running code for filtering to only valid datasets due to error in input")
|
|
630
1284
|
print("using valid datasets filter due to error in input")
|
|
631
1285
|
# Validate images
|
|
632
|
-
images_to_test = [
|
|
1286
|
+
images_to_test = [
|
|
1287
|
+
func() for func in list_functions(national_codes=national_codes)
|
|
1288
|
+
]
|
|
633
1289
|
valid_imgs = keep_valid_images(images_to_test) # Validate images
|
|
634
1290
|
|
|
635
1291
|
# Retry combining images after validation
|
|
@@ -643,20 +1299,61 @@ def combine_datasets():
|
|
|
643
1299
|
|
|
644
1300
|
|
|
645
1301
|
######helper functions to check images
|
|
646
|
-
|
|
647
|
-
|
|
648
1302
|
# list all functions ending with "_prep" (in the current script)
|
|
649
|
-
def list_functions():
|
|
1303
|
+
# def list_functions():
|
|
1304
|
+
# # Use the module's globals to get all defined functions
|
|
1305
|
+
# current_module = inspect.getmodule(inspect.currentframe())
|
|
1306
|
+
# functions = [
|
|
1307
|
+
# func
|
|
1308
|
+
# for name, func in inspect.getmembers(current_module, inspect.isfunction)
|
|
1309
|
+
# if name.endswith("_prep")
|
|
1310
|
+
# ]
|
|
1311
|
+
# return functions
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
def list_functions(national_codes=None):
|
|
1315
|
+
"""
|
|
1316
|
+
Returns a list of functions that end with "_prep" and either:
|
|
1317
|
+
- Start with "g_" (global/regional products)
|
|
1318
|
+
- Start with any provided national code prefix (nXX_)
|
|
1319
|
+
|
|
1320
|
+
Args:
|
|
1321
|
+
national_codes: List of ISO2 country codes (without the 'n' prefix)
|
|
1322
|
+
"""
|
|
650
1323
|
# Use the module's globals to get all defined functions
|
|
651
1324
|
current_module = inspect.getmodule(inspect.currentframe())
|
|
1325
|
+
|
|
1326
|
+
# If national_codes is None, default to an empty list
|
|
1327
|
+
if national_codes is None:
|
|
1328
|
+
national_codes = []
|
|
1329
|
+
|
|
1330
|
+
# Create prefixes list with proper formatting ('n' + code + '_')
|
|
1331
|
+
allowed_prefixes = ["g_"] + [f"n{code.lower()}_" for code in national_codes]
|
|
1332
|
+
|
|
1333
|
+
# Filter functions in a single pass
|
|
652
1334
|
functions = [
|
|
653
1335
|
func
|
|
654
1336
|
for name, func in inspect.getmembers(current_module, inspect.isfunction)
|
|
655
1337
|
if name.endswith("_prep")
|
|
1338
|
+
and any(name.startswith(prefix) for prefix in allowed_prefixes)
|
|
656
1339
|
]
|
|
1340
|
+
|
|
657
1341
|
return functions
|
|
658
1342
|
|
|
659
1343
|
|
|
1344
|
+
# # IN PROGRESS - expected behaviour
|
|
1345
|
+
# def filter_by_prefix_list(input_list=None,prefix_list=None):
|
|
1346
|
+
|
|
1347
|
+
# if input_list is None:
|
|
1348
|
+
# print ("No function in list")
|
|
1349
|
+
# if prefix_list is None:
|
|
1350
|
+
# print ("No prefixes listed by which to filter")
|
|
1351
|
+
# if input_list is not None:
|
|
1352
|
+
# for prefix in prefix_list:
|
|
1353
|
+
# if element.startsWith(prefix):
|
|
1354
|
+
# list.
|
|
1355
|
+
|
|
1356
|
+
|
|
660
1357
|
def keep_valid_images(images):
|
|
661
1358
|
"""Keeps only valid images."""
|
|
662
1359
|
valid_images = []
|