Skip to content

Commit 38772b7

Browse files
authored
Merge pull request #102 from bopen/improve-coverage
Improve coverage
2 parents 2fe8eca + d417aaa commit 38772b7

6 files changed

+100
-24
lines changed

tests/test_10_esa_safe.py

+23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pathlib
22
import typing as T
3+
from xml.etree import ElementTree
34

45
import pytest
56
import xmlschema
@@ -165,6 +166,28 @@ def test_parse_annotation_filename() -> None:
165166
esa_safe.parse_annotation_filename("")
166167

167168

169+
def test_findtext() -> None:
170+
tree = ElementTree.fromstring("<root><child>text</child></root>")
171+
172+
res = esa_safe.findtext(tree, ".//child")
173+
174+
assert res == "text"
175+
176+
with pytest.raises(ValueError):
177+
esa_safe.findtext(tree, ".//dummy")
178+
179+
180+
def test_findall() -> None:
181+
tree = ElementTree.fromstring("<root><c1>text</c1><c2></c2></root>")
182+
183+
res = esa_safe.findall(tree, ".//c1")
184+
185+
assert res == ["text"]
186+
187+
with pytest.raises(ValueError):
188+
esa_safe.findall(tree, ".//c2")
189+
190+
168191
@pytest.mark.parametrize("product_id,expected", SENTINEL1_ATTRIBUTES.items())
169192
def test_parse_manifest_sentinel1(
170193
product_id: str, expected: T.Dict[str, T.Any]

tests/test_20_sentinel1.py

+58-7
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@
5353
/ "measurement"
5454
/ "s1a-s3-slc-vh-20210401t152855-20210401t152914-037258-04638e-001.tiff"
5555
)
56-
GRD_IW_VV_annotation = (
56+
GRD_IW = (
5757
DATA_FOLDER
5858
/ "S1B_IW_GRDH_1SDV_20210401T052623_20210401T052648_026269_032297_ECC8.SAFE"
59+
)
60+
GRD_IW_VV_annotation = (
61+
GRD_IW
5962
/ "annotation"
6063
/ "s1b-iw-grd-vv-20210401t052623-20210401t052648-026269-032297-001.xml"
6164
)
@@ -70,6 +73,9 @@ def test_get_fs_path() -> None:
7073

7174
assert path == str((SLC_IW / "manifest.safe"))
7275

76+
with pytest.raises(TypeError):
77+
sentinel1.get_fs_path("*", fs=fs, storage_options={})
78+
7379
with pytest.raises(ValueError):
7480
sentinel1.get_fs_path("non-existent-path/*")
7581

@@ -288,14 +294,20 @@ def test_crop_burst_dataset() -> None:
288294
sentinel1.crop_burst_dataset(swath_ds, burst_id=1)
289295

290296

297+
def test_mosaic_slc_iw() -> None:
298+
da = sentinel1.open_sentinel1_dataset(SLC_IW_V340, group="IW1/HH")
299+
300+
res = sentinel1.mosaic_slc_iw(da)
301+
302+
assert isinstance(res, xr.Dataset)
303+
304+
291305
def test_calibrate_amplitude() -> None:
292306
swath_ds = sentinel1.open_sentinel1_dataset(SLC_IW, group="IW1/VH")
293307
burst_ds = sentinel1.crop_burst_dataset(swath_ds, burst_index=8)
294-
calibration_ds = sentinel1.open_calibration_dataset(SLC_IW1_VV_calibration)
308+
cal_ds = sentinel1.open_sentinel1_dataset(SLC_IW, group="IW1/VH/calibration")
295309

296-
res = sentinel1.calibrate_amplitude(
297-
burst_ds.measurement, calibration_ds["betaNought"]
298-
)
310+
res = sentinel1.calibrate_amplitude(burst_ds.measurement, cal_ds["betaNought"])
299311

300312
assert set(res.dims) == {"azimuth_time", "slant_range_time"}
301313
assert np.issubdtype(res.dtype, np.complex64)
@@ -304,11 +316,50 @@ def test_calibrate_amplitude() -> None:
304316
def test_calibrate_intensity() -> None:
305317
swath_ds = sentinel1.open_sentinel1_dataset(SLC_IW, group="IW1/VH")
306318
burst_ds = sentinel1.crop_burst_dataset(swath_ds, burst_index=8)
307-
calibration_ds = sentinel1.open_calibration_dataset(SLC_IW1_VV_calibration)
319+
cal_ds = sentinel1.open_sentinel1_dataset(SLC_IW, group="IW1/VH/calibration")
320+
321+
res = sentinel1.calibrate_intensity(burst_ds.measurement, cal_ds["betaNought"])
322+
323+
assert set(res.dims) == {"azimuth_time", "slant_range_time"}
324+
assert np.issubdtype(res.dtype, np.float32)
325+
326+
cal_ds["betaNought"].attrs.pop("long_name")
308327

309328
res = sentinel1.calibrate_intensity(
310-
burst_ds.measurement, calibration_ds["betaNought"]
329+
burst_ds.measurement, cal_ds["betaNought"], as_db=True
311330
)
312331

313332
assert set(res.dims) == {"azimuth_time", "slant_range_time"}
314333
assert np.issubdtype(res.dtype, np.float32)
334+
335+
res = sentinel1.calibrate_intensity(
336+
burst_ds.measurement,
337+
cal_ds["betaNought"],
338+
as_db=True,
339+
min_db=None,
340+
)
341+
342+
assert np.issubdtype(res.dtype, np.float32)
343+
344+
345+
def test_slant_range_time_to_ground_range() -> None:
346+
swath_ds = sentinel1.open_sentinel1_dataset(SLC_IW, group="IW1/VV")
347+
swath = swath_ds.measurement[:1000, :1000]
348+
cc_ds = sentinel1.open_sentinel1_dataset(
349+
GRD_IW, group="IW/VV/coordinate_conversion"
350+
)
351+
352+
res = sentinel1.slant_range_time_to_ground_range(
353+
swath.azimuth_time, swath.slant_range_time, cc_ds
354+
)
355+
356+
assert isinstance(res, xr.DataArray)
357+
358+
359+
def test_do_override_product_files() -> None:
360+
template = "{dirname}/{prefix}{swath}-{polarization}{ext}"
361+
_, product_files = esa_safe.parse_manifest_sentinel1(SLC_S3 / "manifest.safe")
362+
363+
res = sentinel1.do_override_product_files(template, product_files)
364+
365+
assert "./annotation/s3-vv.xml" in res

tests/test_40_reformat_netcdf4.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
def test_to_group_netcdf(tmpdir: T.Any) -> None:
1414
product_path = (
1515
DATA_FOLDER
16-
/ "S1B_IW_SLC__1SDV_20210401T052622_20210401T052650_026269_032297_EFA4.SAFE"
16+
/ "S1B_IW_GRDH_1SDV_20210401T052623_20210401T052648_026269_032297_ECC8.SAFE"
1717
)
1818
tmp_path = str(tmpdir.join("tmp.nc"))
19-
groups = {"IW1/VV/gcp": "IW1/VV/gcp", "IW2/VH/attitude": "IW2/VH/attitude"}
19+
groups = {"IW/VV/gcp": "IW/VV/gcp", "IW/VH/attitude": "IW/VH/attitude"}
2020

2121
reformat.to_group_netcdf(product_path, tmp_path, groups, engine="netcdf4")
22+
23+
reformat.to_group_netcdf(product_path, tmp_path, engine="netcdf4")

tests/test_40_reformat_zarr.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
def test_to_group_zarr(tmpdir: T.Any) -> None:
1414
product_path = (
1515
DATA_FOLDER
16-
/ "S1B_IW_SLC__1SDV_20210401T052622_20210401T052650_026269_032297_EFA4.SAFE"
16+
/ "S1B_IW_GRDH_1SDV_20210401T052623_20210401T052648_026269_032297_ECC8.SAFE"
1717
)
1818
tmp_path = str(tmpdir.join("tmp.zarr"))
19-
groups = {"IW1/VV/gcp": "IW1/VV/gcp", "IW2/VH/attitude": "IW2/VH/attitude"}
19+
groups = {"IW/VV/gcp": "IW/VV/gcp", "IW/VH/attitude": "IW/VH/attitude"}
2020

2121
reformat.to_group_zarr(product_path, tmp_path, groups)
22+
23+
reformat.to_group_zarr(product_path, tmp_path)

xarray_sentinel/esa_safe.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,26 @@ def parse_tag_as_list(
7070

7171

7272
def findtext(
73-
tree: ElementTree.ElementTree,
73+
tree: ElementTree.Element,
7474
query: str,
7575
namespaces: T.Dict[str, str] = SENTINEL1_NAMESPACES,
7676
) -> str:
7777
value = tree.findtext(query, namespaces=namespaces)
7878
if value is None:
79-
raise ValueError(f"query={query} returned None")
79+
raise ValueError(f"{query=} returned None")
8080
return value
8181

8282

8383
def findall(
84-
tree: ElementTree.ElementTree,
84+
tree: ElementTree.Element,
8585
query: str,
8686
namespaces: T.Dict[str, str] = SENTINEL1_NAMESPACES,
8787
) -> T.List[str]:
8888
tags = tree.findall(query, namespaces=namespaces)
8989
values: T.List[str] = []
9090
for tag in tags:
9191
if tag.text is None:
92-
raise ValueError(f"query={query} returned None")
92+
raise ValueError(f"{query=} returned None")
9393
values.append(tag.text)
9494
return values
9595

@@ -108,26 +108,26 @@ def parse_manifest_sentinel1(
108108
manifest_path: PathOrFileType,
109109
) -> T.Tuple[T.Dict[str, T.Any], T.Dict[str, T.Tuple[str, str, str, str, str]]]:
110110
# We use ElementTree because we didn't find a XSD definition for the manifest
111-
manifest = ElementTree.parse(manifest_path)
111+
manifest = ElementTree.parse(manifest_path).getroot()
112112

113113
family_name = findtext(manifest, ".//safe:platform/safe:familyName")
114114
if family_name != "SENTINEL-1":
115-
raise ValueError(f"familyName={family_name} not supported")
115+
raise ValueError(f"{family_name=} not supported")
116116

117117
number = findtext(manifest, ".//safe:platform/safe:number")
118118
mode = findtext(manifest, ".//s1sarl1:instrumentMode/s1sarl1:mode")
119119
swaths = findall(manifest, ".//s1sarl1:instrumentMode/s1sarl1:swath")
120120

121121
orbit_number = findall(manifest, ".//safe:orbitNumber")
122122
if len(orbit_number) != 2 or orbit_number[0] != orbit_number[1]:
123-
raise ValueError(f"orbitNumber={orbit_number} not supported")
123+
raise ValueError(f"{orbit_number=} not supported")
124124

125125
relative_orbit_number = findall(manifest, ".//safe:relativeOrbitNumber")
126126
if (
127127
len(relative_orbit_number) != 2
128128
or relative_orbit_number[0] != relative_orbit_number[1]
129129
):
130-
raise ValueError(f"relativeOrbitNumber={relative_orbit_number} not supported")
130+
raise ValueError(f"{relative_orbit_number=} not supported")
131131

132132
orbit_pass = findtext(manifest, ".//s1:pass")
133133
if orbit_pass not in {"ASCENDING", "DESCENDING"}:

xarray_sentinel/sentinel1.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -604,16 +604,14 @@ def crop_burst_dataset(
604604
try:
605605
burst_index = bursts_ids.index(burst_id)
606606
except ValueError:
607-
raise KeyError(
608-
f"'burst_id' {burst_id} not found in product 'bursts_ids': {bursts_ids}"
609-
)
607+
raise KeyError(f"{burst_id=} not found in product {bursts_ids=}")
610608
else:
611609
raise TypeError(
612610
"one keyword between 'burst_index' and 'azimuth_anx_time' must be defined"
613611
)
614612

615613
if burst_index < 0 or burst_index >= pol_dataset.attrs["number_of_bursts"]:
616-
raise IndexError(f"burst_index={burst_index} out of bounds")
614+
raise IndexError(f"{burst_index=} out of bounds")
617615

618616
lines_per_burst = pol_dataset.attrs["lines_per_burst"]
619617
ds = pol_dataset.sel(
@@ -688,7 +686,7 @@ def calibrate_intensity(
688686
def slant_range_time_to_ground_range(
689687
azimuth_time: xr.DataArray,
690688
slant_range_time: xr.DataArray,
691-
coordinate_conversion: xr.DataArray,
689+
coordinate_conversion: xr.Dataset,
692690
) -> xr.DataArray:
693691
slant_range = SPEED_OF_LIGHT / 2.0 * slant_range_time
694692
cc = coordinate_conversion.interp(azimuth_time=azimuth_time)

0 commit comments

Comments
 (0)