From bc044d2367d8925716025b63eb195c6331238e12 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Mon, 20 Jan 2025 16:50:31 +0100 Subject: [PATCH 1/5] Fix keepdims --- mikeio/dfs/_dfs.py | 18 ++++++++++++++---- tests/test_consistency.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/mikeio/dfs/_dfs.py b/mikeio/dfs/_dfs.py index 174627f44..7e43d9c52 100644 --- a/mikeio/dfs/_dfs.py +++ b/mikeio/dfs/_dfs.py @@ -393,8 +393,13 @@ def read( else: shape = (nt, self.nz, self.ny, self.nx) # type: ignore + spdims = self.geometry.default_dims + dims = ["time"] + dims.extend(spdims) + if single_time_selected and not keepdims: shape = shape[1:] + dims = dims[1:] data_list: list[np.ndarray] = [ np.ndarray(shape=shape, dtype=dtype) for _ in range(n_items) @@ -415,7 +420,10 @@ def read( d = d.reshape(self.ny, self.nx) # type: ignore if single_time_selected: - data_list[item] = d + if keepdims: + data_list[item] = np.atleast_2d(d) + else: + data_list[item] = d else: data_list[item][i] = d @@ -426,10 +434,12 @@ def read( items = _get_item_info(self._dfs.ItemInfo, item_numbers) self._dfs.Close() + return Dataset( - data_list, - time, - items, + data=data_list, + time=time, + items=items, + dims=tuple(dims), geometry=self.geometry, validate=False, dt=self._timestep, diff --git a/tests/test_consistency.py b/tests/test_consistency.py index ce1c9e7de..5626194c3 100644 --- a/tests/test_consistency.py +++ b/tests/test_consistency.py @@ -574,3 +574,38 @@ def test_concat_dfsu3d_single_timesteps_generic_vs_dataset(tmp_path): assert ds3.end_time == ds4.end_time assert ds3.n_items == ds4.n_items assert ds3.n_timesteps == ds4.n_timesteps + + +def test_keepdims_removes_singleton_dimension() -> None: + ds1 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfs1", time=0, keepdims=False + ) + assert ds1.dims == ("x",) + + ds2 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfs1", time=0, keepdims=True + ) + assert ds2.dims == ("time", "x") + + ds3 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfs2", time=0, keepdims=False + ) + assert ds3.dims == ( + "y", + "x", + ) + + ds4 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfs2", time=0, keepdims=True + ) + assert ds4.dims == ("time", "y", "x") + + ds5 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfsu", time=0, keepdims=False + ) + assert ds5.dims == ("element",) + + ds6 = mikeio.read( + filename="tests/testdata/consistency/oresundHD.dfsu", time=0, keepdims=True + ) + assert ds6.dims == ("time", "element") From 8cda132a9894b88751fa50f8bdbe1e084b021f69 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Tue, 21 Jan 2025 08:22:37 +0100 Subject: [PATCH 2/5] Refactor --- mikeio/__init__.py | 5 ++--- mikeio/dfs/_dfs.py | 19 ++++++------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/mikeio/__init__.py b/mikeio/__init__.py index 2c6949755..6d575199f 100644 --- a/mikeio/__init__.py +++ b/mikeio/__init__.py @@ -121,11 +121,10 @@ def read( ext = Path(filename).suffix.lower() if "dfs" not in ext: - raise ValueError("mikeio.read() is only supported for Dfs files") + raise ValueError("mikeio.read() is only supported for dfs files") dfs = open(filename) - if isinstance(dfs, Mesh): - raise ValueError("mikeio.read() is not supported for Mesh files") + assert not isinstance(dfs, Mesh) return dfs.read(items=items, time=time, keepdims=keepdims, **kwargs) diff --git a/mikeio/dfs/_dfs.py b/mikeio/dfs/_dfs.py index 7e43d9c52..6ae6dd672 100644 --- a/mikeio/dfs/_dfs.py +++ b/mikeio/dfs/_dfs.py @@ -391,6 +391,7 @@ def read( elif self._ndim == 2: shape = (nt, self.ny, self.nx) # type: ignore else: + # TODO this is not used, since Dfs3 has a separate .read method shape = (nt, self.nz, self.ny, self.nx) # type: ignore spdims = self.geometry.default_dims @@ -411,8 +412,8 @@ def read( for item in range(n_items): itemdata = self._dfs.ReadItemTimeStep(item_numbers[item] + 1, int(it)) - src = itemdata.Data - d = src + d = itemdata.Data + assert d.ndim == 1 d[d == self.deletevalue] = np.nan @@ -461,17 +462,9 @@ def _get_item_info(self, item_numbers: Sequence[int]) -> list[ItemInfo]: list[Iteminfo] """ - items = [] - for item in item_numbers: - name = self._dfs.ItemInfo[item].Name - eumItem = self._dfs.ItemInfo[item].Quantity.Item - eumUnit = self._dfs.ItemInfo[item].Quantity.Unit - itemtype = EUMType(eumItem) - unit = EUMUnit(eumUnit) - data_value_type = self._dfs.ItemInfo[item].ValueType - item_info = ItemInfo(name, itemtype, unit, data_value_type) - items.append(item_info) - return items + infos = self._dfs.ItemInfo + nos = item_numbers + return [ItemInfo.from_mikecore_dynamic_item_info(infos[i]) for i in nos] @property def geometry(self) -> Any: From a3c77dc7a28d0b5f7822e60aca9002724b404bd3 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Tue, 21 Jan 2025 08:24:45 +0100 Subject: [PATCH 3/5] Removed imports --- mikeio/dfs/_dfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mikeio/dfs/_dfs.py b/mikeio/dfs/_dfs.py index 6ae6dd672..97c8497f4 100644 --- a/mikeio/dfs/_dfs.py +++ b/mikeio/dfs/_dfs.py @@ -19,7 +19,7 @@ from mikecore.Projections import Cartography from ..dataset import Dataset -from ..eum import EUMType, EUMUnit, ItemInfo, ItemInfoList +from ..eum import ItemInfo, ItemInfoList from ..exceptions import ItemsError from .._time import DateTimeSelector From 0f432d767ac6469ab6e796f5bfa69bc209f31de1 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Wed, 22 Jan 2025 15:28:53 +0100 Subject: [PATCH 4/5] Revert --- mikeio/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mikeio/__init__.py b/mikeio/__init__.py index 6d575199f..499d93df4 100644 --- a/mikeio/__init__.py +++ b/mikeio/__init__.py @@ -124,7 +124,8 @@ def read( raise ValueError("mikeio.read() is only supported for dfs files") dfs = open(filename) - assert not isinstance(dfs, Mesh) + if isinstance(dfs, Mesh): + raise ValueError("mikeio.read() is not supported for Mesh files") return dfs.read(items=items, time=time, keepdims=keepdims, **kwargs) From 56a2e79036faa8cfd559de600ec7ed840c1f3052 Mon Sep 17 00:00:00 2001 From: Henrik Andersson Date: Fri, 24 Jan 2025 08:08:20 +0100 Subject: [PATCH 5/5] Add time dim if needed --- mikeio/dfs/_dfs.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mikeio/dfs/_dfs.py b/mikeio/dfs/_dfs.py index 97c8497f4..f7263438d 100644 --- a/mikeio/dfs/_dfs.py +++ b/mikeio/dfs/_dfs.py @@ -394,13 +394,12 @@ def read( # TODO this is not used, since Dfs3 has a separate .read method shape = (nt, self.nz, self.ny, self.nx) # type: ignore - spdims = self.geometry.default_dims - dims = ["time"] - dims.extend(spdims) + dims = self.geometry.default_dims if single_time_selected and not keepdims: shape = shape[1:] - dims = dims[1:] + else: + dims = ["time"] + list(dims) data_list: list[np.ndarray] = [ np.ndarray(shape=shape, dtype=dtype) for _ in range(n_items) @@ -421,10 +420,7 @@ def read( d = d.reshape(self.ny, self.nx) # type: ignore if single_time_selected: - if keepdims: - data_list[item] = np.atleast_2d(d) - else: - data_list[item] = d + data_list[item] = np.atleast_2d(d) if keepdims else d else: data_list[item][i] = d