Skip to content

Commit

Permalink
fix: T3D header is not correct (#356)
Browse files Browse the repository at this point in the history
* Added ZSurf option for verticalPositionType.

* Added a child class that inherrits from QuantityUnitPair that also has a vertical position index.

* Fixed the aliases to adhere to the 2D3D manual.

* Reverted Time Interpolation back to the original timeInterpolation. Updated testcase data to reflect the changes made to some keywords in the .bc file.

* Added support for the timeInterpolation keyword when creating a T3D forcing.

* Removed the QuantityUnitPositionPair class again, in favour of a better design.

* Fixed failing tests as a result of making the QuantityUnitPair a BaseModel instead of a NamedTuple.

* Added new test for the QuantityUnitPair.

* Added documentation to the VerticalInterpolation enum.

* Added documentation to the TimeInterpolation enum.

* Added documentation to the QuantityUnitPair class.

* Updated documentation of ForcingBase to the new documentation style.

* Added documenation to the T3D class.

* Added validation: Ensure the first QuantityUnitPair is for `time`.

* Intermediate commit of the new validation.

* Intermediate commit of the new validation.

* Fixed an error in the validator and fixed formatting.

* Fixed some testcases and added a couple of testcases.

* Added additional testcases

* Added additional testcases

* Added additional test cases.

* Updated reference data for T3D

* Updated the remaining documentation for this file.

* autoformat: isort & black

* Fixed a bug with the `number_of_verticalpositions`. Implemented review comments. Updated testcases.

* Use `Vertical Position` instead of `verticalpositionindex`

* Updated keywords for the T3D header and added a test to ensure loading a .bc with T3D block works as expected.

* Fixed code smells.

* Fixed code smells.

* Add failing testcase that should pass

* Added a way to support the 'Vertical Position Specification' keyword when reading .bc files.

* autoformat: isort & black

* Updated the keywords to the new keywords.

* Updated error message to be more clear

* Added backwards compatibility for the keywords in the .bc file that use spaces.

* autoformat: isort & black

* Added backwards compatibility for the `Time Interpolation` keyword in a [TimeSeries] block.

* Added error when the user forgot to specify the vertpositions field that is required in the root_validator

* Fixed the default enum values for timeinterpolation and verticalinterpolation.

* Removed the check for this unit as it causes problems on the build server and is not super relevant.

* Removed the ForcingBackwardsCompatibilityHelper and instead added a generic root validator that can be used to rename keys.

* autoformat: isort & black

* Update hydrolib/core/io/bc/models.py

Co-authored-by: Prisca van der Sluis <36264671+priscavdsluis@users.noreply.github.com>

* Implemented review comments.

* autoformat: isort & black

Co-authored-by: tim-vd-aardweg <tim-vd-aardweg@users.noreply.github.com>
Co-authored-by: Prisca van der Sluis <36264671+priscavdsluis@users.noreply.github.com>
Co-authored-by: Arthur van Dam <arthurvd@gmail.com>
Co-authored-by: priscavdsluis <priscavdsluis@users.noreply.github.com>
  • Loading branch information
5 people committed Oct 14, 2022
1 parent 7beb285 commit 6b99312
Show file tree
Hide file tree
Showing 8 changed files with 757 additions and 77 deletions.
254 changes: 230 additions & 24 deletions hydrolib/core/io/bc/models.py

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions hydrolib/core/io/ini/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,28 @@ def is_valid_coordinates_with_num_coordinates_specification() -> bool:
raise ValueError(error)

return root_validator(allow_reuse=True)(validate_location_specification)


def get_key_renaming_root_validator(keys_to_rename: Dict[str, List[str]]):
"""
Gets a root validator that renames the provided keys to support backwards compatibility.
Args:
keys_to_rename Dict[str, List[str]]: Dictionary of keys and a list of old keys that
should be converted to the current key.
"""

def rename_keys(cls, values: Dict) -> Dict:
for current_keyword, old_keywords in keys_to_rename.items():
if current_keyword in values:
continue

for old_keyword in old_keywords:
if (value := values.get(old_keyword)) is not None:
values[current_keyword] = value
del values[old_keyword]
break

return values

return root_validator(allow_reuse=True, pre=True)(rename_keys)
1 change: 1 addition & 0 deletions hydrolib/core/io/mdu/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class AutoStartOption(IntEnum):
Enum class containing the valid values for the AutoStart
attribute in the [General][hydrolib.core.io.mdu.models.General] class.
"""

no = 0
autostart = 1
autostartstop = 2
Expand Down
43 changes: 43 additions & 0 deletions tests/data/reference/bc/t3d_backwards_compatibility.bc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# written by HYDROLIB-core 0.3.0

[General]
fileVersion = 1.01
fileType = boundConds

[Forcing]
name = boundary_timeseries
function = timeseries
Time Interpolation = blockTo
offset = 1.23
factor = 2.34
quantity = time
unit = minutes since 2015-01-01 00:00:00
quantity = dischargebnd
unit = m³/s
0.0 1.23
60.0 2.34
120.0 3.45

[Forcing]
name = boundary_t3d
function = t3d
offset = 1.23
factor = 2.34
Vertical Position Specification = 3.45 4.56 5.67
Vertical Interpolation = log
Vertical Position Type = percBed
Time Interpolation = linear
quantity = time
unit = m
quantity = salinitybnd
unit = ppt
Vertical Position = 1
quantity = salinitybnd
unit = ppt
Vertical Position = 2
quantity = salinitybnd
unit = ppt
Vertical Position = 3
0.0 1.0 2.0 3.0
60.0 4.0 5.0 6.0
120.0 7.0 8.0 9.0
34 changes: 19 additions & 15 deletions tests/data/reference/bc/test.bc
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,25 @@ unit = deg
60.0 3.45 4.56

[Forcing]
name = boundary_t3d
function = t3d
offset = 1.23
factor = 2.34
verticalPositions = 3.45 4.56 5.67
verticalInterpolation = log
verticalPositionType = percBed
quantity = time
unit = m
quantity = salinitybnd
unit = ppt
quantity = salinitybnd
unit = ppt
quantity = salinitybnd
unit = ppt
name = boundary_t3d
function = t3d
offset = 1.23
factor = 2.34
vertPositions = 3.45 4.56 5.67
vertInterpolation = log
vertPositionType = percBed
timeInterpolation = linear
quantity = time
unit = m
quantity = salinitybnd
unit = ppt
vertPositionIndex = 1
quantity = salinitybnd
unit = ppt
vertPositionIndex = 2
quantity = salinitybnd
unit = ppt
vertPositionIndex = 3
0.0 1.0 2.0 3.0
60.0 4.0 5.0 6.0
120.0 7.0 8.0 9.0
Expand Down
41 changes: 41 additions & 0 deletions tests/io/ini/test_util.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from typing import Dict, List, Optional

import pytest
from pydantic import Extra
from pydantic.error_wrappers import ValidationError

from hydrolib.core.basemodel import BaseModel
from hydrolib.core.io.ini.util import (
LocationValidationConfiguration,
LocationValidationFieldNames,
get_key_renaming_root_validator,
get_location_specification_rootvalidator,
)

Expand Down Expand Up @@ -198,3 +200,42 @@ def test_correct_1d_fields_locationtype_is_added(
values
)
assert validated_values == expected_values


class TestGetKeyRenamingRootValidator:
class DummyModel(BaseModel):
"""Dummy model to test the validation of the location specification."""

randomproperty: str

validator = get_key_renaming_root_validator(
{
"randomproperty": [
"randomProperty",
"random_property",
"oldRandomProperty",
],
}
)

class Config:
extra = Extra.allow

@pytest.mark.parametrize(
"old_key", ["randomProperty", "random_property", "oldRandomProperty"]
)
def test_old_keys_are_correctly_renamed_to_current_keyword(self, old_key: str):
values = {old_key: "randomString"}

model = TestGetKeyRenamingRootValidator.DummyModel(**values)

assert model.randomproperty == "randomString"

def test_unknown_key_still_raises_error(self):
values = {"randomKeyThatNeverExisted": "randomString"}

with pytest.raises(ValidationError) as error:
TestGetKeyRenamingRootValidator.DummyModel(**values)

expected_message = "field required"
assert expected_message in str(error.value)
Loading

0 comments on commit 6b99312

Please sign in to comment.