Skip to content

Commit 5950e2d

Browse files
authored
Merge branch 'main' into fillna
2 parents 8ae6bfc + 40bf35b commit 5950e2d

23 files changed

+422
-351
lines changed

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
# Ruff version.
4+
rev: v0.8.6
5+
hooks:
6+
# Run the linter.
7+
- id: ruff
8+
# Run the formatter.
9+
- id: ruff-format

mikeio/__init__.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from __future__ import annotations
22
from importlib.metadata import PackageNotFoundError, version
33
from pathlib import Path
4-
from platform import architecture
54
from collections.abc import Sequence
65
from typing import Any
76

@@ -15,9 +14,6 @@
1514
__dfs_version__: int = 220
1615

1716

18-
if "64" not in architecture()[0]:
19-
raise Exception("This library has not been tested for a 32 bit system.")
20-
2117
from .dataset import DataArray, Dataset, from_pandas, from_polars
2218
from .dfs import Dfs0, Dfs1, Dfs2, Dfs3
2319
from .dfsu import Dfsu, Mesh, Dfsu2DH, Dfsu2DV, Dfsu3D, DfsuSpectral
@@ -121,7 +117,9 @@ def read(
121117
ext = Path(filename).suffix.lower()
122118

123119
if "dfs" not in ext:
124-
raise ValueError("mikeio.read() is only supported for dfs files")
120+
raise ValueError(
121+
"mikeio.read() is only supported for dfs files. Use mikeio.open for mesh files."
122+
)
125123

126124
dfs = open(filename)
127125
if isinstance(dfs, Mesh):

mikeio/_track.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def _extract_track(
1919
end_time: pd.Timestamp,
2020
timestep: float,
2121
geometry: GeometryFM2D,
22-
track: str | Dataset | pd.DataFrame,
22+
track: str | Path | Dataset | pd.DataFrame,
2323
items: Sequence[ItemInfo],
2424
item_numbers: Sequence[int],
2525
time_steps: Sequence[int],
@@ -36,6 +36,8 @@ def _extract_track(
3636
match track:
3737
case str():
3838
times, coords = _get_track_data_from_file(track)
39+
case Path():
40+
times, coords = _get_track_data_from_file(str(track))
3941
case Dataset():
4042
times, coords = _get_track_data_from_dataset(track)
4143
case pd.DataFrame():
@@ -193,20 +195,3 @@ def _get_track_data_from_file(track: str) -> tuple[pd.DatetimeIndex, np.ndarray]
193195
coords = df.iloc[:, 0:2].to_numpy(copy=True)
194196

195197
return times, coords
196-
197-
198-
def _find_end_index(t_rel: pd.Index, end_time: pd.Timestamp) -> int:
199-
# largest idx for which (times - self.end_time)<=0
200-
tmp = np.where(t_rel <= 0)[0]
201-
if len(tmp) == 0:
202-
raise ValueError("No time overlap!")
203-
i_end = tmp[-1]
204-
return i_end
205-
206-
207-
def _find_start_index(t_rel: pd.Index, start_time: pd.Timestamp) -> int:
208-
tmp = np.where(t_rel >= 0)[0]
209-
if len(tmp) == 0:
210-
raise ValueError("No time overlap!")
211-
i_start = tmp[0] # smallest idx for which t_rel>=0
212-
return i_start

mikeio/dataset/_dataarray.py

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@
8181
Grid3D,
8282
]
8383

84+
IndexType = Union[int, slice, Sequence[int], np.ndarray, None]
85+
8486

8587
class _DataArraySpectrumToHm0:
8688
def __init__(self, da: "DataArray") -> None:
@@ -98,12 +100,9 @@ def __call__(self, tail: bool = True) -> "DataArray":
98100
dims = tuple([d for d in self.da.dims if d not in ("frequency", "direction")])
99101
item = ItemInfo(EUMType.Significant_wave_height)
100102
g = self.da.geometry
101-
if isinstance(g, GeometryFMPointSpectrum):
102-
if g.x is not None and g.y is not None:
103-
geometry: Any = GeometryPoint2D(x=g.x, y=g.y)
104-
else:
105-
geometry = GeometryUndefined()
106-
elif isinstance(g, GeometryFMLineSpectrum):
103+
geometry: Any = GeometryUndefined()
104+
105+
if isinstance(g, GeometryFMLineSpectrum):
107106
geometry = Grid1D(
108107
nx=g.n_nodes,
109108
dx=1.0,
@@ -119,8 +118,6 @@ def __call__(self, tail: bool = True) -> "DataArray":
119118
element_table=g.element_table,
120119
element_ids=g.element_ids,
121120
)
122-
else:
123-
geometry = GeometryUndefined()
124121

125122
return DataArray(
126123
data=Hm0,
@@ -407,7 +404,11 @@ def type(self) -> EUMType:
407404
@property
408405
def unit(self) -> EUMUnit:
409406
"""EUMUnit."""
410-
return self.item.unit
407+
return self.item._unit
408+
409+
@unit.setter
410+
def unit(self, value: EUMUnit) -> None:
411+
self.item.unit = value
411412

412413
@property
413414
def start_time(self) -> datetime:
@@ -613,9 +614,18 @@ def __setitem__(self, key: Any, value: np.ndarray) -> None:
613614

614615
def isel(
615616
self,
616-
idx: int | Sequence[int] | slice | None = None,
617+
idx: IndexType = None,
618+
*,
619+
time: IndexType = None,
620+
x: IndexType = None,
621+
y: IndexType = None,
622+
z: IndexType = None,
623+
element: IndexType = None,
624+
node: IndexType = None,
625+
layer: IndexType = None,
626+
frequency: IndexType = None,
627+
direction: IndexType = None,
617628
axis: int | str = 0,
618-
**kwargs: Any,
619629
) -> "DataArray":
620630
"""Return a new DataArray whose data is given by
621631
integer indexing along the specified dimension(s).
@@ -646,11 +656,17 @@ def isel(
646656
y index, by default None
647657
z : int, optional
648658
z index, by default None
659+
layer: int, optional
660+
layer index, only used in dfsu 3d
661+
direction: int, optional
662+
direction index, only used in sprectra
663+
frequency: int, optional
664+
frequencey index, only used in spectra
665+
node: int, optional
666+
node index, only used in spectra
649667
element : int, optional
650668
Bounding box of coordinates (left lower and right upper)
651669
to be selected, by default None
652-
**kwargs: Any
653-
Not used
654670
655671
Returns
656672
-------
@@ -683,10 +699,23 @@ def isel(
683699
```
684700
685701
"""
686-
if isinstance(self.geometry, Grid2D) and ("x" in kwargs and "y" in kwargs):
687-
idx_x = kwargs["x"]
688-
idx_y = kwargs["y"]
689-
return self.isel(x=idx_x).isel(y=idx_y)
702+
if isinstance(self.geometry, Grid2D) and (x is not None and y is not None):
703+
return self.isel(x=x).isel(y=y)
704+
kwargs = {
705+
k: v
706+
for k, v in dict(
707+
time=time,
708+
x=x,
709+
y=y,
710+
z=z,
711+
element=element,
712+
node=node,
713+
layer=layer,
714+
frequency=frequency,
715+
direction=direction,
716+
).items()
717+
if v is not None
718+
}
690719
for dim in kwargs:
691720
if dim in self.dims:
692721
axis = dim
@@ -727,7 +756,7 @@ def isel(
727756
spatial_axis = axis - 1 if self.dims[0] == "time" else axis
728757
geometry = self.geometry.isel(idx, axis=spatial_axis)
729758

730-
# TOOD this is ugly
759+
# TODO this is ugly
731760
if isinstance(geometry, _GeometryFMLayered):
732761
node_ids, _ = self.geometry._get_nodes_and_table_for_elements(
733762
idx, node_layers="all"
@@ -770,7 +799,12 @@ def sel(
770799
self,
771800
*,
772801
time: str | pd.DatetimeIndex | "DataArray" | None = None,
773-
**kwargs: Any,
802+
x: float | slice | None = None,
803+
y: float | slice | None = None,
804+
z: float | slice | None = None,
805+
coords: np.ndarray | None = None,
806+
area: tuple[float, float, float, float] | None = None,
807+
layers: int | str | Sequence[int | str] | None = None,
774808
) -> "DataArray":
775809
"""Return a new DataArray whose data is given by
776810
selecting index labels along the specified dimension(s).
@@ -809,8 +843,6 @@ def sel(
809843
layer(s) to be selected: "top", "bottom" or layer number
810844
from bottom 0,1,2,... or from the top -1,-2,... or as
811845
list of these; only for layered dfsu, by default None
812-
**kwargs: Any
813-
Additional keyword arguments
814846
815847
Returns
816848
-------
@@ -852,24 +884,32 @@ def sel(
852884
```
853885
854886
"""
887+
# time is not part of kwargs
888+
kwargs = {
889+
k: v
890+
for k, v in dict(
891+
x=x, y=y, z=z, area=area, coords=coords, layers=layers
892+
).items()
893+
if v is not None
894+
}
855895
if any([isinstance(v, slice) for v in kwargs.values()]):
856-
return self._sel_with_slice(kwargs)
896+
return self._sel_with_slice(kwargs) # type: ignore
857897

858898
da = self
859899

860900
# select in space
861901
if len(kwargs) > 0:
862902
idx = self.geometry.find_index(**kwargs)
903+
904+
# TODO this seems fragile
863905
if isinstance(idx, tuple):
864906
# TODO: support for dfs3
865907
assert len(idx) == 2
866-
t_ax_offset = 1 if self._has_time_axis else 0
867908
ii, jj = idx
868909
if jj is not None:
869-
da = da.isel(idx=jj, axis=(0 + t_ax_offset))
910+
da = da.isel(y=jj)
870911
if ii is not None:
871-
sp_axis = 0 if (jj is not None and len(jj) == 1) else 1
872-
da = da.isel(idx=ii, axis=(sp_axis + t_ax_offset))
912+
da = da.isel(x=ii)
873913
else:
874914
da = da.isel(idx, axis="space")
875915

@@ -1895,7 +1935,7 @@ def to_dfs(self, filename: str | Path, **kwargs: Any) -> None:
18951935
Dfs0 only: set the dfs data type of the written data
18961936
to e.g. np.float64, by default: DfsSimpleType.Float (=np.float32)
18971937
**kwargs: Any
1898-
Additional keyword arguments, e.g. dtype for dfs0
1938+
additional arguments passed to the writing function, e.g. dtype for dfs0
18991939
19001940
"""
19011941
self._to_dataset().to_dfs(filename, **kwargs)

0 commit comments

Comments
 (0)