From 05c96c614ada90b835ad7b06276554c8f31c16af Mon Sep 17 00:00:00 2001 From: Alessandro Amici Date: Tue, 27 Apr 2021 12:00:38 +0200 Subject: [PATCH 1/5] Add initial sentinel1 accessor that raises when not used on backend Dataset (more or less) --- tests/test_xarray.py | 16 ++++++++++++++++ xarray_sentinel/sentinel1.py | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 6ddc5d3..0d2269e 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -1,6 +1,7 @@ import pathlib import numpy as np +import pytest import xarray as xr DATA_FOLDER = pathlib.Path(__file__).parent / "data" @@ -49,6 +50,21 @@ def test_open_dataset_root() -> None: assert isinstance(res, xr.Dataset) +def test_open_dataset_root_accessor() -> None: + product_path = ( + DATA_FOLDER + / "S1B_IW_SLC__1SDV_20210401T052622_20210401T052650_026269_032297_EFA4.SAFE" + ) + res = xr.open_dataset(product_path, engine="sentinel-1") # type: ignore + + assert res.sentinel1.group is None + + res1 = xr.zeros_like(res, 0) + + with pytest.raises(AttributeError): + res1.sentinel1.group + + def test_open_dataset_orbit() -> None: manifest_path = ( DATA_FOLDER diff --git a/xarray_sentinel/sentinel1.py b/xarray_sentinel/sentinel1.py index 837df6c..64cbfc8 100644 --- a/xarray_sentinel/sentinel1.py +++ b/xarray_sentinel/sentinel1.py @@ -318,9 +318,25 @@ def open_dataset( annotation_path=annotation_path, chunks=chunks, ) + # add backend specific metadata in the Dataset enconding + ds.encoding = { + "engine": "sentinel-1", + "group": group, + "filename_or_obj": filename_or_obj, + } return ds +@xr.register_dataset_accessor("sentinel1") +class Sentinel1Accessor: + def __init__(self, xarray_obj): + self.disabled = True + if xarray_obj.encoding.get("engine") == "sentinel-1": + self.disabled = False + self.filename_or_obj = xarray_obj.encoding["filename_or_obj"] + self.group = xarray_obj.encoding["group"] + + class Sentinel1Backend(xr.backends.common.BackendEntrypoint): def open_dataset( # type: ignore self, From 8e9c83df902b10156bbbe1631d6edede820389ba Mon Sep 17 00:00:00 2001 From: Alessandro Amici Date: Tue, 27 Apr 2021 12:08:20 +0200 Subject: [PATCH 2/5] Fix typing --- xarray_sentinel/sentinel1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xarray_sentinel/sentinel1.py b/xarray_sentinel/sentinel1.py index 64cbfc8..70c51ed 100644 --- a/xarray_sentinel/sentinel1.py +++ b/xarray_sentinel/sentinel1.py @@ -327,9 +327,9 @@ def open_dataset( return ds -@xr.register_dataset_accessor("sentinel1") +@xr.register_dataset_accessor("sentinel1") # type: ignore class Sentinel1Accessor: - def __init__(self, xarray_obj): + def __init__(self, xarray_obj: xr.Dataset) -> None: self.disabled = True if xarray_obj.encoding.get("engine") == "sentinel-1": self.disabled = False From a3be30662a553aef5353d2682f370d9e731b6f9b Mon Sep 17 00:00:00 2001 From: Alessandro Amici Date: Tue, 27 Apr 2021 12:23:01 +0200 Subject: [PATCH 3/5] More precise error exception and message --- tests/test_xarray.py | 4 ++-- xarray_sentinel/sentinel1.py | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 0d2269e..497a084 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -61,8 +61,8 @@ def test_open_dataset_root_accessor() -> None: res1 = xr.zeros_like(res, 0) - with pytest.raises(AttributeError): - res1.sentinel1.group + with pytest.raises(RuntimeError): + res1.sentinel1 def test_open_dataset_orbit() -> None: diff --git a/xarray_sentinel/sentinel1.py b/xarray_sentinel/sentinel1.py index 70c51ed..b0d6128 100644 --- a/xarray_sentinel/sentinel1.py +++ b/xarray_sentinel/sentinel1.py @@ -330,11 +330,10 @@ def open_dataset( @xr.register_dataset_accessor("sentinel1") # type: ignore class Sentinel1Accessor: def __init__(self, xarray_obj: xr.Dataset) -> None: - self.disabled = True - if xarray_obj.encoding.get("engine") == "sentinel-1": - self.disabled = False - self.filename_or_obj = xarray_obj.encoding["filename_or_obj"] - self.group = xarray_obj.encoding["group"] + if xarray_obj.encoding.get("engine") != "sentinel-1": + raise TypeError("not a 'sentinel-1' 'Dataset'") + self.filename_or_obj = xarray_obj.encoding["filename_or_obj"] + self.group = xarray_obj.encoding["group"] class Sentinel1Backend(xr.backends.common.BackendEntrypoint): From 60eeaaf20e36b3a7995befbab84c1f51ed46032d Mon Sep 17 00:00:00 2001 From: Alessandro Amici Date: Tue, 27 Apr 2021 12:33:00 +0200 Subject: [PATCH 4/5] Sync with xarray raising behaviour --- tests/test_xarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 497a084..94ff71b 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -61,7 +61,7 @@ def test_open_dataset_root_accessor() -> None: res1 = xr.zeros_like(res, 0) - with pytest.raises(RuntimeError): + with pytest.raises(TypeError): res1.sentinel1 From 5c2d604655bc6156c4eec018db808e7c38917573 Mon Sep 17 00:00:00 2001 From: Alessandro Amici Date: Tue, 27 Apr 2021 14:35:02 +0200 Subject: [PATCH 5/5] More concise naming --- xarray_sentinel/sentinel1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xarray_sentinel/sentinel1.py b/xarray_sentinel/sentinel1.py index a8d1dfc..14c307c 100644 --- a/xarray_sentinel/sentinel1.py +++ b/xarray_sentinel/sentinel1.py @@ -293,13 +293,13 @@ def compute_burst_centres(gcp: xr.Dataset) -> T.Tuple[np.ndarray, np.ndarray]: def open_dataset( - product_urlpath: esa_safe.PathType, + urlpath: esa_safe.PathType, drop_variables: T.Optional[T.Tuple[str]] = None, group: T.Optional[str] = None, chunks: T.Optional[T.Union[int, T.Dict[str, int]]] = None, fs: T.Optional[fsspec.AbstractFileSystem] = None, ) -> xr.Dataset: - fs, manifest_path = get_fs_path(product_urlpath, fs) + fs, manifest_path = get_fs_path(urlpath, fs) if fs.isdir(manifest_path): manifest_path = os.path.join(manifest_path, "manifest.safe") @@ -345,7 +345,7 @@ def open_dataset( ds.encoding = { "engine": "sentinel-1", "group": group, - "filename_or_obj": filename_or_obj, + "urlpath": urlpath, } return ds @@ -355,7 +355,7 @@ class Sentinel1Accessor: def __init__(self, xarray_obj: xr.Dataset) -> None: if xarray_obj.encoding.get("engine") != "sentinel-1": raise TypeError("not a 'sentinel-1' 'Dataset'") - self.filename_or_obj = xarray_obj.encoding["filename_or_obj"] + self.urlpath = xarray_obj.encoding["urlpath"] self.group = xarray_obj.encoding["group"]