Skip to content

Commit 40d7bdc

Browse files
authored
Merge pull request #830 from DHI/change_dfs_datatype
Change dfs datatype
2 parents 8ef98f3 + d243656 commit 40d7bdc

File tree

3 files changed

+149
-23
lines changed

3 files changed

+149
-23
lines changed

mikeio/generic.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"quantile",
5252
"scale",
5353
"sum",
54+
"change_datatype",
5455
]
5556

5657

@@ -94,14 +95,19 @@ def _clone(
9495
start_time: datetime | None = None,
9596
timestep: float | None = None,
9697
items: Sequence[int | DfsDynamicItemInfo] | None = None,
98+
datatype: int | None = None,
9799
) -> DfsFile:
98100
source = DfsFileFactory.DfsGenericOpen(str(infilename))
99101
fi = source.FileInfo
100102

101103
builder = DfsBuilder.Create(fi.FileTitle, "mikeio", __dfs_version__)
102104

103105
# Set up the header
104-
builder.SetDataType(fi.DataType)
106+
if datatype is None:
107+
builder.SetDataType(fi.DataType)
108+
else:
109+
builder.SetDataType(datatype)
110+
105111
builder.SetGeographicalProjection(fi.Projection)
106112

107113
# Copy time axis
@@ -959,3 +965,49 @@ def _get_repeated_items(
959965
new_items.append(item)
960966

961967
return new_items
968+
969+
970+
def change_datatype(
971+
infilename: str | pathlib.Path,
972+
outfilename: str | pathlib.Path,
973+
datatype: int,
974+
) -> None:
975+
"""Change datatype of a DFS file.
976+
977+
The data type tag is used to classify the file within a specific modeling context,
978+
such as MIKE 21. There is no global standard for these tags—they are interpreted
979+
locally within a model setup.
980+
981+
Application developers can use these tags to classify files such as
982+
bathymetries, input data, or result files according to their own conventions.
983+
984+
Default data type values assigned by MikeIO when creating new files are:
985+
- dfs0: datatype=1
986+
- dfs1-3: datatype=0
987+
- dfsu: datatype=2001
988+
989+
Parameters
990+
----------
991+
infilename : str | pathlib.Path
992+
input filename
993+
outfilename : str | pathlib.Path
994+
output filename
995+
datatype: int
996+
DataType to be used for the output file
997+
998+
Examples
999+
--------
1000+
>>> change_datatype("in.dfsu", "out.dfsu", datatype=107)
1001+
1002+
"""
1003+
dfs_out = _clone(infilename, outfilename, datatype=datatype)
1004+
dfs_in = DfsFileFactory.DfsGenericOpen(infilename)
1005+
1006+
# Copy dynamic item data
1007+
sourceData = dfs_in.ReadItemTimeStepNext()
1008+
while sourceData:
1009+
dfs_out.WriteItemTimeStepNext(sourceData.Time, sourceData.Data)
1010+
sourceData = dfs_in.ReadItemTimeStepNext()
1011+
1012+
dfs_out.Close()
1013+
dfs_in.Close()

notebooks/Generic.ipynb

Lines changed: 61 additions & 21 deletions
Large diffs are not rendered by default.

tests/test_generic.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,18 @@
33
import pandas as pd
44
import mikeio
55
from mikeio import generic
6-
from mikeio.generic import scale, diff, sum, extract, avg_time, fill_corrupt, add
6+
from mikeio.generic import (
7+
scale,
8+
diff,
9+
sum,
10+
extract,
11+
avg_time,
12+
fill_corrupt,
13+
add,
14+
change_datatype,
15+
)
716
import pytest
17+
from mikecore.DfsFileFactory import DfsFileFactory
818

919

1020
def test_add_constant(tmp_path: Path) -> None:
@@ -638,3 +648,27 @@ def test_fill_corrupt_data(tmp_path: Path) -> None:
638648
orig = mikeio.read(infile)
639649
extracted = mikeio.read(fp)
640650
assert extracted.n_timesteps == orig.n_timesteps
651+
652+
653+
def test_change_datatype_dfs0(tmp_path: Path) -> None:
654+
infilename = "tests/testdata/random.dfs0"
655+
outfilename = str(tmp_path / "random_datatype107.dfs0")
656+
OUT_DATA_TYPE = 107
657+
658+
change_datatype(infilename, outfilename, datatype=OUT_DATA_TYPE)
659+
dfs_out = DfsFileFactory.DfsGenericOpen(outfilename)
660+
dfs_in = DfsFileFactory.DfsGenericOpen(infilename)
661+
662+
n_timesteps_in = dfs_in.FileInfo.TimeAxis.NumberOfTimeSteps
663+
n_timesteps_out = dfs_out.FileInfo.TimeAxis.NumberOfTimeSteps
664+
datatype_out = dfs_out.FileInfo.DataType
665+
666+
dfs_out.Close()
667+
dfs_in.Close()
668+
669+
assert datatype_out == OUT_DATA_TYPE
670+
assert n_timesteps_in == n_timesteps_out
671+
# Also check that data is not modified
672+
org = mikeio.read(infilename).to_numpy()
673+
new = mikeio.read(outfilename).to_numpy()
674+
assert np.allclose(org, new, rtol=1e-08, atol=1e-10, equal_nan=True)

0 commit comments

Comments
 (0)