Skip to content

Commit

Permalink
Level4 (#171)
Browse files Browse the repository at this point in the history
* Changed the band names to match the config files. Also updated vegetation , lifeform and water seasonality to correctly replace nodata

* Fixed a typo in the name of the expression in the water sesonality

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update the path to the urban model on s3

* Differentiate mangroves and other aquatic veg (#170)

* differentiate mangroves and other aquatic veg

* fix level1 test

---------

Co-authored-by: Emma Ai <[email protected]>

* Fixed a few errors after rewriting the logic on aquatic vegetation

* Ensured nodata is replaced with 255 in all level4 plugins

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove debugging code

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Corrected the implementation of water seasonality and water persistence. Also made a range of other mappings at Level 4 based on the latest understanding of Collection 2

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Mock the veg and bare thresholds in the unit test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Cleaned the code and removed redundant checks at level4

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Applied more code cleaning

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Emma Ai <[email protected]>
Co-authored-by: Emma Ai <[email protected]>
  • Loading branch information
4 people authored Nov 24, 2024
1 parent 52c37a0 commit 37fd7fa
Show file tree
Hide file tree
Showing 21 changed files with 336 additions and 477 deletions.
14 changes: 7 additions & 7 deletions odc/stats/plugins/l34_utils/l4_bare_gradation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@

def bare_gradation(xx: xr.Dataset, bare_threshold, veg_cover):

# Map any data > 100 ---> 100
# Address nodata
bs_pc_50 = expr_eval(
"where((a>100)&(a!=nodata), 100, a)",
"where((a!=a), nodata, a)",
{"a": xx.bs_pc_50.data},
name="mark_veg",
dtype="uint8",
name="mark_bare_gradation_nodata",
dtype="float32",
**{"nodata": NODATA},
)

# 60% <= data --> 15
bs_mask = expr_eval(
"where((a>=m)&(a!=nodata), 15, a)",
{"a": bs_pc_50},
name="mark_veg",
name="mark_bare",
dtype="uint8",
**{"m": bare_threshold[1], "nodata": NODATA},
)
Expand All @@ -29,7 +29,7 @@ def bare_gradation(xx: xr.Dataset, bare_threshold, veg_cover):
bs_mask = expr_eval(
"where((a>=m)&(a<n), 12, b)",
{"a": bs_pc_50, "b": bs_mask},
name="mark_veg",
name="mark_very_sparse_veg",
dtype="uint8",
**{"m": bare_threshold[0], "n": bare_threshold[1]},
)
Expand All @@ -38,7 +38,7 @@ def bare_gradation(xx: xr.Dataset, bare_threshold, veg_cover):
bs_mask = expr_eval(
"where(a<m, 10, b)",
{"a": bs_pc_50, "b": bs_mask},
name="mark_veg",
name="mark_sparse_veg",
dtype="uint8",
**{"m": bare_threshold[0]},
)
Expand Down
75 changes: 38 additions & 37 deletions odc/stats/plugins/l34_utils/l4_cultivated.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,93 +3,94 @@
NODATA = 255


def lc_l4_cultivated(l34, level3, lifeform, veg_cover):
def lc_l4_cultivated(l34, level3, woody, veg_cover):

l4 = expr_eval(
"where((d==110)&(a==111)&(b==10)&(c==1), 9, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l34},
name="mark_cultivated",
dtype="uint8",
woody = expr_eval(
"where((a!=a), nodata, a)",
{"a": woody.data},
name="mask_woody_nodata",
dtype="float32",
**{"nodata": NODATA},
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==12)&(c==1), 10, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==113), 2, d)",
{"a": level3, "b": woody, "d": l34},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==13)&(c==1), 11, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==114), 3, d)",
{"a": level3, "b": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

# the 4-8 classes can't happen in LC since cultivated class will not be classified if vegetation doesn't exist.
# skip these classes in level4

l4 = expr_eval(
"where((d==110)&(a==111)&(b==15)&(c==1), 12, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==10)&(c==113), 9, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==16)&(c==1), 13, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==12)&(c==113), 10, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==10)&(c==2), 14, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==13)&(c==113), 11, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
l4 = expr_eval(
"where((d==110)&(a==111)&(b==12)&(c==2), 15, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==15)&(c==113), 12, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==13)&(c==2), 16, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==16)&(c==113), 13, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==15)&(c==2), 17, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==10)&(c==114), 14, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==16)&(c==2), 18, d)",
{"a": level3, "b": veg_cover, "c": lifeform, "d": l4},
"where((a==111)&(b==12)&(c==114), 15, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==1), 2, d)",
{"a": level3, "b": lifeform, "d": l4},
"where((a==111)&(b==13)&(c==114), 16, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

l4 = expr_eval(
"where((d==110)&(a==111)&(b==2), 3, d)",
{"a": level3, "b": lifeform, "d": l4},
"where((a==111)&(b==15)&(c==114), 17, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)

# the 4-8 classes can't happen in LC since cultivated class will not be classified if vegetation doesn't exist.
# skip these classes in level4

l4 = expr_eval(
"where((d==110)&(a==111), 1, d)",
{"a": level3, "d": l4},
"where((a==111)&(b==16)&(c==114), 18, d)",
{"a": level3, "b": veg_cover, "c": woody, "d": l4},
name="mark_cultivated",
dtype="uint8",
)
Expand Down
38 changes: 35 additions & 3 deletions odc/stats/plugins/l34_utils/l4_natural_aquatic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@

from odc.stats._algebra import expr_eval

NODATA = 255

def natural_auquatic_veg(l4, veg_cover, water_seasonality):

def natural_auquatic_veg(l4, veg_cover, water_season):

# mark woody/herbaceous
# mangroves -> woody
# everything else -> herbaceous

water_seasonality = expr_eval(
"where((a==a), a, nodata)",
{
"a": water_season,
},
name="mark_water_season",
dtype="float32",
**{"nodata": NODATA},
)

res = expr_eval(
"where((a==124), 56, a)",
{
Expand Down Expand Up @@ -102,7 +115,7 @@ def natural_auquatic_veg(l4, veg_cover, water_seasonality):
)

res = expr_eval(
"where((a==252)&(b==10), 80, a)",
"where((a==252)&(b==10), 79, a)",
{
"a": res,
"b": veg_cover,
Expand All @@ -112,7 +125,7 @@ def natural_auquatic_veg(l4, veg_cover, water_seasonality):
)

res = expr_eval(
"where((a==251)&(b==10), 81, a)",
"where((a==251)&(b==10), 80, a)",
{
"a": res,
"b": veg_cover,
Expand Down Expand Up @@ -282,4 +295,23 @@ def natural_auquatic_veg(l4, veg_cover, water_seasonality):
dtype="uint8",
)

# There are cases where a tile falls over water.
# In these cases, the PC will have no data so we map back 251-254 to their corresponding classes
res = expr_eval(
"where((a>=251)&(a<=252), 57, a)",
{
"a": res,
},
name="mark_final",
dtype="uint8",
)
res = expr_eval(
"where((a>=253)&(a<=254), 58, a)",
{
"a": res,
},
name="mark_final",
dtype="uint8",
)

return res
Loading

0 comments on commit 37fd7fa

Please sign in to comment.