diff --git a/mikecore/DfsFactory.py b/mikecore/DfsFactory.py index 9a096c4..5b4b4ca 100644 --- a/mikecore/DfsFactory.py +++ b/mikecore/DfsFactory.py @@ -58,7 +58,7 @@ def CreateCustomBlock(self, name, data): # region Spatial axis factory methods def CreateAxisDummy(self, numberOfValues): - return DfsAxisEqD1(0, numberOfValues, 0, 1) + return DfsAxisEqD1.CreateDummyAxis(numberOfValues) def CreateAxisEqD0(self): return DfsAxisEqD0() diff --git a/tests/test_dfs_basic.py b/tests/test_dfs_basic.py index fb70f39..9026d80 100644 --- a/tests/test_dfs_basic.py +++ b/tests/test_dfs_basic.py @@ -1,5 +1,6 @@ import ctypes +import numpy as np import pytest from mikecore.DfsDLL import DfsDLL @@ -51,6 +52,46 @@ def test_read_itemtimestep(): assert data.Data[0] == 104 +@pytest.mark.parametrize( + "opener, filename, reshape, shape", + [ + (DfsFileFactory.DfsGenericOpen, "testdata/TemporalNeqCal.dfs0", False, (1,)), + (DfsFileFactory.Dfs2FileOpen, "testdata/OresundHD.dfs2", False, (6461,)), + (DfsFileFactory.Dfs2FileOpen, "testdata/OresundHD.dfs2", True, (71, 91)), + (DfsFileFactory.Dfs3FileOpen, "testdata/OresundHD.dfs3", True, (72, 94, 41)), + (DfsFileFactory.DfsGenericOpen, "testdata/OdenseHD2D.dfsu", False, (724,)), + ], + ids=["dfs0", "dfs2", "dfs2-reshape", "dfs3-reshape", "dfsu"], +) +def test_read_itemtimestep_into_given_itemdata(opener, filename, reshape, shape): + """ReadItemTimeStep(itemData, j) fills and returns the itemData it is given, + with the same values as ReadItemTimeStep(itemNumber, j) allocates.""" + dfs = opener(filename) + numberOfTimeSteps = dfs.FileInfo.TimeAxis.NumberOfTimeSteps + assert numberOfTimeSteps > 1 + + changed = False + for itemNumber in range(1, len(dfs.ItemInfo) + 1): + # Flat, so the reshape cases reshape it on read + itemData = dfs.CreateEmptyItemData(itemNumber) + buffer = itemData.Data + # Backwards, so the buffer holds another timestep's values before each read + for j in reversed(range(numberOfTimeSteps)): + expected = dfs.ReadItemTimeStep(itemNumber, j, reshape) + before = buffer.copy() + + assert dfs.ReadItemTimeStep(itemData, j, reshape) is itemData + assert np.shares_memory(itemData.Data, buffer) + assert shape == itemData.Data.shape + assert j == itemData.TimeStepIndex + assert expected.Time == itemData.Time + np.testing.assert_array_equal(expected.Data, itemData.Data) + changed = changed or not np.array_equal(before, buffer) + dfs.Close() + + assert changed, "every read left the buffer as it was" + + def test_error_reporting(): print(DfsDLL.dfsErrorString(1000)) diff --git a/tests/test_dfs_static_item.py b/tests/test_dfs_static_item.py index 5217b67..cf62992 100644 --- a/tests/test_dfs_static_item.py +++ b/tests/test_dfs_static_item.py @@ -113,7 +113,7 @@ def test_static_item(self): axis = staticItem.SpatialAxis assert SpaceAxisType.EqD1 == axis.AxisType assert 1 == axis.Dimension - # TODO: Assert.AreEqual(eumUnit.eumUmeter, axis.AxisUnit + assert eumUnit.eumUmeter == axis.AxisUnit assert 3 * 3636 == axis.XCount assert 0 == axis.X0 assert 1 == axis.Dx diff --git a/tests/test_dfsbuilder.py b/tests/test_dfsbuilder.py index 681b77f..7e518a2 100644 --- a/tests/test_dfsbuilder.py +++ b/tests/test_dfsbuilder.py @@ -8,6 +8,7 @@ DfsStaticItemBuilder, ) from mikecore.DfsFactory import DfsFactory +from mikecore.DfsFile import SpaceAxisType from mikecore.DfsFileFactory import DfsFileFactory from mikecore.eum import eumUnit, eumQuantity, eumItem @@ -243,6 +244,58 @@ def test_validate_ignores_encode_key_of_dfs0(tmp_path): assert item.Data.tolist() == [7] +@pytest.mark.parametrize( + "create, axisType, axisUnit, size", + [ + ( + lambda f: f.CreateAxisDummy(5), + SpaceAxisType.EqD1, + eumUnit.eumUUnitUndefined, + 5, + ), + (lambda f: f.CreateAxisEqD0(), SpaceAxisType.EqD0, eumUnit.eumUmeter, 1), + ( + lambda f: f.CreateAxisEqD1(eumUnit.eumUfeet, 5, 0, 1), + SpaceAxisType.EqD1, + eumUnit.eumUfeet, + 5, + ), + ( + lambda f: f.CreateAxisEqD2(eumUnit.eumUkilometer, 4, 0, 1, 3, 0, 1), + SpaceAxisType.EqD2, + eumUnit.eumUkilometer, + 12, + ), + ( + lambda f: f.CreateAxisEqD3(eumUnit.eumUmeter, 4, 0, 1, 3, 0, 1, 2, 0, 1), + SpaceAxisType.EqD3, + eumUnit.eumUmeter, + 24, + ), + ], + ids=["Dummy", "EqD0", "EqD1", "EqD2", "EqD3"], +) +def test_factory_axis_is_written_and_read_back( + tmp_path, create, axisType, axisUnit, size +): + builder = compressed_builder_for(create(DfsFactory())) + filename = str(tmp_path / "axis.dfs") + builder.CreateFile(filename) + dfs = builder.GetFile() + dfs.WriteItemTimeStepNext(0, np.arange(size, dtype=np.float32)) + dfs.Close() + + dfs = DfsFileFactory.DfsGenericOpen(filename) + axis = dfs.ItemInfo[0].SpatialAxis + item = dfs.ReadItemTimeStepNext() + dfs.Close() + + assert axisType == axis.AxisType + assert axisUnit == axis.AxisUnit + assert item is not None + assert item.Data.tolist() == list(range(size)) + + def test_static_item_builder_reports_missing_data_and_axis(): errors = DfsStaticItemBuilder().Validate() diff --git a/tests/test_dfsu2D.py b/tests/test_dfsu2D.py index 5747cd9..59a89c9 100644 --- a/tests/test_dfsu2D.py +++ b/tests/test_dfsu2D.py @@ -68,9 +68,20 @@ def test_CreateOresundHDTest(self): FileOresundHDDfsu.FileInfoTester(dfsFile) FileOresundHDDfsu.CustomBlockTester(dfsFile) FileOresundHDDfsu.DynamicItemTester(dfsFile) - FileOresundHDDfsu.StaticItemTester(dfsFile) + FileOresundHDDfsu.StaticItemTester(dfsFile, original=False) FileOresundHDDfsu.ReadTester(dfsFile) + def test_ReadOresundHDTest(self): + dfsFile = DfsFileFactory.DfsGenericOpen("testdata/OresundHD.dfsu") + + FileOresundHDDfsu.FileInfoTester(dfsFile) + FileOresundHDDfsu.CustomBlockTester(dfsFile) + FileOresundHDDfsu.DynamicItemTester(dfsFile) + FileOresundHDDfsu.StaticItemTester(dfsFile, original=True) + FileOresundHDDfsu.ReadTester(dfsFile) + + dfsFile.Close() + def test_ReadOdenseHD2DTest(self): filename = "testdata/OdenseHD2D.dfsu" @@ -296,7 +307,7 @@ def test_CreateOresundHDGenericTest(self): FileOresundHDDfsu.FileInfoTester(dfsFile) FileOresundHDDfsu.CustomBlockTester(dfsFile) FileOresundHDDfsu.DynamicItemTester(dfsFile) - FileOresundHDDfsu.StaticItemTester(dfsFile) + FileOresundHDDfsu.StaticItemTester(dfsFile, original=False) FileOresundHDDfsu.ReadTester(dfsFile) def test_ExtractDfsu2DTopLayerFrom3DIsThe2DModel(self): @@ -578,7 +589,7 @@ def DynamicItemTester(dfsFile): Assert.AreEqual(1, axis.Dx) @staticmethod - def StaticItemTester(dfsFile): + def StaticItemTester(dfsFile, original): staticItems = [] staticItemNumber = 1 @@ -638,7 +649,10 @@ def StaticItemTester(dfsFile): axis = staticItem.SpatialAxis Assert.IsNotNull(axis) Assert.AreEqual(1, axis.Dimension) - # TODO: Assert.AreEqual(eumUnit.eumUmeter, axis.AxisUnit); + if original: + Assert.AreEqual(eumUnit.eumUmeter, axis.AxisUnit) + else: + Assert.AreEqual(eumUnit.eumUUnitUndefined, axis.AxisUnit) Assert.AreEqual(2057, axis.XCount) Assert.AreEqual(0, axis.X0) Assert.AreEqual(1, axis.Dx) @@ -703,7 +717,10 @@ def StaticItemTester(dfsFile): axis = staticItem.SpatialAxis Assert.IsNotNull(axis) Assert.AreEqual(1, axis.Dimension) - # TODO: Assert.AreEqual(eumUnit.eumUmeter, axis.AxisUnit); + if original: + Assert.AreEqual(eumUnit.eumUmeter, axis.AxisUnit) + else: + Assert.AreEqual(eumUnit.eumUUnitUndefined, axis.AxisUnit) Assert.AreEqual(3 * 3636, axis.XCount) Assert.AreEqual(0, axis.X0) Assert.AreEqual(1, axis.Dx) @@ -1043,14 +1060,12 @@ def ReadTester(dfsFile): for itemInfo in dfsFile.ItemInfo: itemDatas.append(dfsFile.CreateEmptyItemData(itemInfo)) + # This overload is checked against ReadItemTimeStep(itemNumber, j) for + # every item-timestep in a separate test, so this loop checks only Time. for j in range(13): for i in range(3): itemData = itemDatas[i] - # TODO: Implement? - # dfsFile.ReadItemTimeStep(itemData, j); - itemData = dfsFile.ReadItemTimeStep(i + 1, j) - itemDatas[i] = itemData - Assert.AreEqual(i + 1, itemData.ItemNumber) + dfsFile.ReadItemTimeStep(itemData, j) Assert.AreEqual(j * 86400, itemData.Time) Assert.AreEqual(np.float32(0.22424224), itemDatas[0].Data[0])