Skip to content

Commit 9d4049b

Browse files
emmaaiEmma Ai
andauthored
add water persistence in module a0 (#154)
* add water persistence in module a0 * add water freq band name --------- Co-authored-by: Emma Ai <emma.ai@ga.gov.au>
1 parent b960c1d commit 9d4049b

File tree

2 files changed

+75
-19
lines changed

2 files changed

+75
-19
lines changed

odc/stats/plugins/lc_fc_wo_a0.py

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class StatsVegCount(StatsPluginInterface):
2929
VERSION = "0.0.1"
3030
PRODUCT_FAMILY = "lccs"
3131

32-
BAD_BITS_MASK = dict(cloud=(1 << 6), cloud_shadow=(1 << 5))
32+
BAD_BITS_MASK = {"cloud": (1 << 6), "cloud_shadow": (1 << 5)}
3333

3434
def __init__(
3535
self,
@@ -44,7 +44,7 @@ def __init__(
4444

4545
@property
4646
def measurements(self) -> Tuple[str, ...]:
47-
_measurements = ["veg_frequency"]
47+
_measurements = ["veg_frequency", "water_frequency"]
4848
return _measurements
4949

5050
def native_transform(self, xx):
@@ -80,10 +80,10 @@ def native_transform(self, xx):
8080
# get valid wo pixels, both dry and wet
8181
data = expr_eval(
8282
"where(a|b, a, _nan)",
83-
dict(a=wet.data, b=valid.data),
83+
{"a": wet.data, "b": valid.data},
8484
name="get_valid_pixels",
8585
dtype="float32",
86-
**dict(_nan=np.nan),
86+
**{"_nan": np.nan},
8787
)
8888

8989
# Pick out the fc pixels that have an unmixing error of less than the threshold
@@ -111,30 +111,49 @@ def _veg_or_not(self, xx: xr.Dataset):
111111
# otherwise 0
112112
data = expr_eval(
113113
"where((a>b)|(c>b), 1, 0)",
114-
dict(a=xx["pv"].data, c=xx["npv"].data, b=xx["bs"].data),
114+
{"a": xx["pv"].data, "c": xx["npv"].data, "b": xx["bs"].data},
115115
name="get_veg",
116116
dtype="uint8",
117117
)
118118

119119
# mark nans
120120
data = expr_eval(
121121
"where(a!=a, nodata, b)",
122-
dict(a=xx["pv"].data, b=data),
122+
{"a": xx["pv"].data, "b": data},
123123
name="get_veg",
124124
dtype="uint8",
125-
**dict(nodata=int(NODATA)),
125+
**{"nodata": int(NODATA)},
126126
)
127127

128128
# mark water freq >= 0.5 as 0
129129
data = expr_eval(
130130
"where(a>0, 0, b)",
131-
dict(a=xx["wet"].data, b=data),
131+
{"a": xx["wet"].data, "b": data},
132132
name="get_veg",
133133
dtype="uint8",
134134
)
135135

136136
return data
137137

138+
def _water_or_not(self, xx: xr.Dataset):
139+
# mark water freq > 0.5 as 1
140+
data = expr_eval(
141+
"where(a>0.5, 1, 0)",
142+
{"a": xx["wet"].data},
143+
name="get_water",
144+
dtype="uint8",
145+
)
146+
147+
# mark nans
148+
data = expr_eval(
149+
"where(a!=a, nodata, b)",
150+
{"a": xx["wet"].data, "b": data},
151+
name="get_water",
152+
dtype="uint8",
153+
**{"nodata": int(NODATA)},
154+
)
155+
return data
156+
138157
def _max_consecutive_months(self, data, nodata):
139158
nan_mask = da.ones(data.shape[1:], chunks=data.chunks[1:], dtype="bool")
140159
tmp = da.zeros(data.shape[1:], chunks=data.chunks[1:], dtype="uint8")
@@ -144,44 +163,44 @@ def _max_consecutive_months(self, data, nodata):
144163
# +1 if not nodata
145164
tmp = expr_eval(
146165
"where(a==nodata, b, a+b)",
147-
dict(a=t, b=tmp),
166+
{"a": t, "b": tmp},
148167
name="compute_consecutive_month",
149168
dtype="uint8",
150-
**dict(nodata=nodata),
169+
**{"nodata": nodata},
151170
)
152171

153172
# save the max
154173
max_count = expr_eval(
155174
"where(a>b, a, b)",
156-
dict(a=max_count, b=tmp),
175+
{"a": max_count, "b": tmp},
157176
name="compute_consecutive_month",
158177
dtype="uint8",
159178
)
160179

161180
# reset if not veg
162181
tmp = expr_eval(
163182
"where((a<=0), 0, b)",
164-
dict(a=t, b=tmp),
183+
{"a": t, "b": tmp},
165184
name="compute_consecutive_month",
166185
dtype="uint8",
167186
)
168187

169188
# mark nodata
170189
nan_mask = expr_eval(
171190
"where(a==nodata, b, False)",
172-
dict(a=t, b=nan_mask),
191+
{"a": t, "b": nan_mask},
173192
name="mark_nodata",
174193
dtype="bool",
175-
**dict(nodata=nodata),
194+
**{"nodata": nodata},
176195
)
177196

178197
# mark nodata
179198
max_count = expr_eval(
180199
"where(a, nodata, b)",
181-
dict(a=nan_mask, b=max_count),
200+
{"a": nan_mask, "b": max_count},
182201
name="mark_nodata",
183202
dtype="uint8",
184-
**dict(nodata=int(nodata)),
203+
**{"nodata": int(nodata)},
185204
)
186205
return max_count
187206

@@ -190,14 +209,20 @@ def reduce(self, xx: xr.Dataset) -> xr.Dataset:
190209
xx = xx.groupby("time.month").map(median_ds, dim="spec")
191210

192211
data = self._veg_or_not(xx)
193-
max_count = self._max_consecutive_months(data, NODATA)
212+
max_count_veg = self._max_consecutive_months(data, NODATA)
213+
214+
data = self._water_or_not(xx)
215+
max_count_water = self._max_consecutive_months(data, NODATA)
194216

195217
attrs = xx.attrs.copy()
196218
attrs["nodata"] = int(NODATA)
197219
data_vars = {
198220
"veg_frequency": xr.DataArray(
199-
max_count, dims=xx["wet"].dims[1:], attrs=attrs
200-
)
221+
max_count_veg, dims=xx["wet"].dims[1:], attrs=attrs
222+
),
223+
"water_frequency": xr.DataArray(
224+
max_count_water, dims=xx["wet"].dims[1:], attrs=attrs
225+
),
201226
}
202227
coords = dict((dim, xx.coords[dim]) for dim in xx["wet"].dims[1:])
203228
return xr.Dataset(data_vars=data_vars, coords=coords, attrs=xx.attrs)

tests/test_landcover_plugin_a0.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,23 @@ def test_veg_or_not(fc_wo_dataset):
381381
i += 1
382382

383383

384+
def test_water_or_not(fc_wo_dataset):
385+
stats_veg = StatsVegCount()
386+
xx = stats_veg.native_transform(fc_wo_dataset)
387+
xx = xx.groupby("solar_day").map(partial(StatsVegCount.fuser, None))
388+
yy = stats_veg._water_or_not(xx).compute()
389+
valid_index = (
390+
np.array([0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2]),
391+
np.array([1, 1, 3, 5, 6, 2, 6, 0, 0, 2, 2, 3, 5, 6]),
392+
np.array([0, 3, 2, 1, 3, 5, 6, 0, 2, 1, 4, 2, 5, 6]),
393+
)
394+
expected_value = np.array([0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0])
395+
i = 0
396+
for idx in zip(*valid_index):
397+
assert yy[idx] == expected_value[i]
398+
i += 1
399+
400+
384401
def test_reduce(fc_wo_dataset):
385402
stats_veg = StatsVegCount()
386403
xx = stats_veg.native_transform(fc_wo_dataset)
@@ -400,6 +417,20 @@ def test_reduce(fc_wo_dataset):
400417

401418
assert (xx.veg_frequency.data == expected_value).all()
402419

420+
expected_value = np.array(
421+
[
422+
[0, 255, 1, 255, 255, 255, 255],
423+
[0, 255, 255, 0, 255, 255, 255],
424+
[255, 1, 255, 255, 0, 0, 255],
425+
[255, 255, 0, 255, 255, 255, 255],
426+
[255, 255, 255, 255, 255, 255, 255],
427+
[255, 0, 255, 255, 255, 0, 255],
428+
[255, 255, 255, 0, 255, 255, 1],
429+
]
430+
)
431+
432+
assert (xx.water_frequency.data == expected_value).all()
433+
403434

404435
def test_consecutive_month(consecutive_count):
405436
stats_veg = StatsVegCount()

0 commit comments

Comments
 (0)