Skip to content

Commit dbc97ec

Browse files
authored
Merge pull request #51 from TUDelftGeodesy/44_fix_point_selected_on_water
44 fix point selected on water
2 parents 4eac4c3 + 9d8ea47 commit dbc97ec

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ select = [
8585
"PLE", # Pylint error https://github.com/charliermarsh/ruff#error-ple
8686
]
8787
ignore = [
88-
"D100", "D101", "D104", "D105", "D106", "D107", "D203", "D213"
88+
"D100", "D101", "D104", "D105", "D106", "D107", "D203", "D213", "D413"
8989
] # docstring style
9090

9191
line-length = 88

sarxarray/stack.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ def point_selection(self, threshold, method="amplitude_dispersion", chunks=1000)
5858
"""
5959
match method:
6060
case "amplitude_dispersion":
61+
# Amplitude dispersion thresholding
62+
# Note there can be NaN values in the amplitude dispersion
63+
# However NaN values will not pass this threshold
6164
mask = self._amp_disp() < threshold
6265
case _:
6366
raise NotImplementedError
@@ -111,9 +114,14 @@ def _amp_disp(self, chunk_azimuth=500, chunk_range=500):
111114
{"azimuth": chunk_azimuth, "range": chunk_range, "time": -1}
112115
)
113116

114-
amplitude_dispersion = amplitude.std(axis=t_order) / (
115-
amplitude.mean(axis=t_order) + np.finfo(amplitude.dtype).eps
116-
) # adding epsilon to avoid zero division
117+
# Compoute amplitude dispersion
118+
# By defalut, the mean and std function from Xarray will skip NaN values
119+
# However, if there is NaN value in time series, we want to discard the pixel
120+
# Therefore, we set skipna=False
121+
# Adding epsilon to avoid zero division
122+
amplitude_dispersion = amplitude.std(axis=t_order, skipna=False) / (
123+
amplitude.mean(axis=t_order, skipna=False) + np.finfo(amplitude.dtype).eps
124+
)
117125

118126
return amplitude_dispersion
119127

tests/test_stack.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def test_stack_pointselection_some(self, synthetic_dataset):
7272
synthetic_dataset = synthetic_dataset.slcstack._get_phase()
7373
stm = synthetic_dataset.slcstack.point_selection(
7474
threshold=0.2, method="amplitude_dispersion"
75-
) # select all
75+
) # select some
7676
assert stm.space.shape[0] == 4
7777
assert set([k for k in stm.coords.keys()]).issubset(
7878
["time", "azimuth", "range"]
@@ -81,6 +81,35 @@ def test_stack_pointselection_some(self, synthetic_dataset):
8181
["complex", "amplitude", "phase"]
8282
)
8383

84+
def test_stack_pointselection_nan(self):
85+
data = np.random.rand(10, 10, 10) + 1j * np.random.rand(10, 10, 10)
86+
data[0, 0, 0] = np.nan # introduce a nan
87+
ds_nan = xr.Dataset(
88+
{
89+
"complex": (
90+
("azimuth", "range", "time"),
91+
data,
92+
)
93+
},
94+
coords={
95+
"azimuth": np.arange(600, 610, 1, dtype=int),
96+
"range": np.arange(1400, 1410, 1, dtype=int),
97+
"time": np.arange(1, 11, 1, dtype=int),
98+
},
99+
)
100+
ds_nan = ds_nan.slcstack._get_amplitude()
101+
ds_nan = ds_nan.slcstack._get_phase()
102+
stm = ds_nan.slcstack.point_selection(
103+
threshold=100, method="amplitude_dispersion"
104+
)
105+
assert stm.space.shape[0] == 99 # only the nan is removed
106+
assert set(list(stm.coords.keys())).issubset(
107+
["time", "azimuth", "range"]
108+
)
109+
assert set(list(stm.data_vars.keys())).issubset(
110+
["complex", "amplitude", "phase"]
111+
)
112+
84113

85114
class TestStackMultiLook:
86115
def test_stack_multi_look_mean(self, synthetic_dataset):

0 commit comments

Comments
 (0)