Structure .ini files¶
Structure .ini files contain the definition of hydraulic structures for a D-Flow FM model.
Generic parsing and serializing functionality comes from the generic hydrolib.core.io.ini modules.
A structures.ini file is described by the classes below.
Models¶
structure namespace for storing the contents of an FMModel's structure file.
Bridge (Structure)
pydantic-model
¶
Hydraulic structure with type=bridge
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the bridge input as described in UM Sec.C.12.5.
Compound (Structure)
pydantic-model
¶
Hydraulic structure with type=compound
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the compound input as described in UM Sec.C.12.11.
Culvert (Structure)
pydantic-model
¶
Hydraulic structure with type=culvert
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the culvert input as described in UM Sec.C.12.3.
Dambreak (Structure)
pydantic-model
¶
Hydraulic structure with type=dambreak
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the dambreak input as described in UM Sec.C.12.10.
check_location(values: dict) -> dict
classmethod
¶
Verifies whether the location for this structure contains valid values for numCoordinates, xCoordinates and yCoordinates or instead is using a polyline file.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
values |
dict |
Dictionary of validated values to create a Dambreak. |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When the values dictionary does not contain valid coordinates or polyline file.. |
Returns:
Type | Description |
---|---|
dict |
Dictionary of validated values. |
Source code in hydrolib/core/io/structure/models.py
@root_validator
@classmethod
def check_location(cls, values: dict) -> dict:
"""
Verifies whether the location for this structure contains valid values for
numCoordinates, xCoordinates and yCoordinates or instead is using a polyline file.
Args:
values (dict): Dictionary of validated values to create a Dambreak.
Raises:
ValueError: When the values dictionary does not contain valid coordinates or polyline file..
Returns:
dict: Dictionary of validated values.
"""
if (
Structure.validate_coordinates_in_model(values)
or values.get("polylinefile", None) is not None
):
return values
raise ValueError(
"`num/x/yCoordinates` or `polylineFile` are mandatory for a Dambreak structure."
)
validate_algorithm(value: str) -> DambreakAlgorithm
classmethod
¶
Validates the algorithm parameter for the dambreak structure.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
int |
algorithm value read from the user's input. |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When the value given is not of type int. |
ValueError |
When the value given is not in the range [1,3] |
Returns:
Type | Description |
---|---|
int |
Validated value. |
Source code in hydrolib/core/io/structure/models.py
@validator("algorithm", pre=True)
@classmethod
def validate_algorithm(cls, value: str) -> DambreakAlgorithm:
"""
Validates the algorithm parameter for the dambreak structure.
Args:
value (int): algorithm value read from the user's input.
Raises:
ValueError: When the value given is not of type int.
ValueError: When the value given is not in the range [1,3]
Returns:
int: Validated value.
"""
int_value = -1
try:
int_value = int(value)
except Exception:
raise ValueError("Dambreak algorithm value should be of type int.")
if 0 < int_value <= 3:
return DambreakAlgorithm(int_value)
raise ValueError("Dambreak algorithm value should be 1, 2 or 3.")
validate_dambreak_levels_and_widths(field_value: Optional[pathlib.Path], values: dict) -> Optional[pathlib.Path]
classmethod
¶
Validates whether a dambreak can be created with the given dambreakLevelsAndWidths property. This property should be given when the algorithm value is 3.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
field_value |
Optional[Path] |
Value given for dambreakLevelsAndWidths. |
required |
values |
dict |
Dictionary of values already validated (assuming algorithm is in it). |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When algorithm value is not 3 and field_value has a value. |
Returns:
Type | Description |
---|---|
Optional[Path] |
The value given for dambreakLevelsAndwidths. |
Source code in hydrolib/core/io/structure/models.py
@validator("dambreaklevelsandwidths")
@classmethod
def validate_dambreak_levels_and_widths(
cls, field_value: Optional[Path], values: dict
) -> Optional[Path]:
"""
Validates whether a dambreak can be created with the given dambreakLevelsAndWidths
property. This property should be given when the algorithm value is 3.
Args:
field_value (Optional[Path]): Value given for dambreakLevelsAndWidths.
values (dict): Dictionary of values already validated (assuming algorithm is in it).
Raises:
ValueError: When algorithm value is not 3 and field_value has a value.
Returns:
Optional[Path]: The value given for dambreakLevelsAndwidths.
"""
# Retrieve the algorithm value (if not found use 0).
algorithm_value = values.get("algorithm", 0)
if field_value is not None and algorithm_value != 3:
# dambreakLevelsAndWidths can only be set when algorithm = 3
raise ValueError(
f"Dambreak field dambreakLevelsAndWidths can only be set when algorithm = 3, current value: {algorithm_value}."
)
return field_value
DambreakAlgorithm (int, Enum)
¶
An enumeration.
FlowDirection (str, Enum)
¶
Enum class containing the valid values for the allowedFlowDirection attribute in several subclasses of Structure.
GateOpeningHorizontalDirection (str, Enum)
¶
Horizontal opening direction of gate door[s].
GeneralStructure (Structure)
pydantic-model
¶
Hydraulic structure with type=generalStructure
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the orifice input as described in UM Sec.C.12.9.
Orientation (str, Enum)
¶
Enum class containing the valid values for the orientation attribute in several subclasses of Structure.
Orifice (Structure)
pydantic-model
¶
Hydraulic structure with type=orifice
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the orifice input as described in UM Sec.C.12.7.
Pump (Structure)
pydantic-model
¶
Hydraulic structure with type=pump
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the pump input as described in UM Sec.C.12.6.
Structure (INIBasedModel)
pydantic-model
¶
check_location(values: dict) -> dict
classmethod
¶
Validates the location of the structure based on the given parameters. For instance, if a branchid is given, then it is expected also the chainage, otherwise numcoordinates xcoordinates and ycoordinates shall be expected.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
values |
dict |
Dictionary of values validated for the new structure. |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When branchid or chainage values are not valid (empty strings). |
ValueError |
When the number of xcoordinates and ycoordinates do not match numcoordinates. |
Returns:
Type | Description |
---|---|
dict |
Dictionary of values validated for the new structure. |
Source code in hydrolib/core/io/structure/models.py
@root_validator
@classmethod
def check_location(cls, values: dict) -> dict:
"""
Validates the location of the structure based on the given parameters.
For instance, if a branchid is given, then it is expected also the chainage,
otherwise numcoordinates xcoordinates and ycoordinates shall be expected.
Args:
values (dict): Dictionary of values validated for the new structure.
Raises:
ValueError: When branchid or chainage values are not valid (empty strings).
ValueError: When the number of xcoordinates and ycoordinates do not match numcoordinates.
Returns:
dict: Dictionary of values validated for the new structure.
"""
filtered_values = {k: v for k, v in values.items() if v is not None}
structype = filtered_values.get("type", "").lower()
# TODO This seems to be a bit of a hack.
if not (structype == "compound" or issubclass(cls, (Compound, Dambreak))):
# Compound structure does not require a location specification.
only_coordinates_structures = dict(
longculvert="LongCulvert", dambreak="Dambreak"
)
coordinates_in_model = Structure.validate_coordinates_in_model(
filtered_values
)
# Exception -> LongCulvert requires coordinates_in_model, but not branchId and chainage.
if structype in only_coordinates_structures.keys():
assert (
coordinates_in_model
), f"`num/x/yCoordinates` are mandatory for a {only_coordinates_structures[structype]} structure."
branch_and_chainage_in_model = (
Structure.validate_branch_and_chainage_in_model(filtered_values)
)
assert (
branch_and_chainage_in_model or coordinates_in_model
), "Specify location either by setting `branchId` and `chainage` or `num/x/yCoordinates` fields."
return values
validate(v)
classmethod
¶
Try to iniatialize subclass based on the type
field.
This field is compared to each type
field of the derived models of Structure
.
The derived model with an equal structure type will be initialized.
Exceptions:
Type | Description |
---|---|
ValueError |
When the given type is not a known structure type. |
Source code in hydrolib/core/io/structure/models.py
@classmethod
def validate(cls, v):
"""Try to iniatialize subclass based on the `type` field.
This field is compared to each `type` field of the derived models of `Structure`.
The derived model with an equal structure type will be initialized.
Raises:
ValueError: When the given type is not a known structure type.
"""
# should be replaced by discriminated unions once merged
# https://github.com/samuelcolvin/pydantic/pull/2336
if isinstance(v, dict):
for c in cls.__subclasses__():
if (
c.__fields__.get("type").default.lower()
== v.get("type", "").lower()
):
v = c(**v)
break
else:
raise ValueError(
f"Type of {cls.__name__} with id={v.get('id', '')} and type={v.get('type', '')} is not recognized."
)
return super().validate(v)
validate_branch_and_chainage_in_model(values: dict) -> bool
staticmethod
¶
Static method to validate whether the given branchid and chainage values match the expectation of a new structure.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
values |
dict |
Dictionary of values to be used to generate a structure. |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When the value for branchid or chainage are not valid. |
Returns:
Type | Description |
---|---|
bool |
Result of valid branchid / chainage in dictionary. |
Source code in hydrolib/core/io/structure/models.py
@staticmethod
def validate_branch_and_chainage_in_model(values: dict) -> bool:
"""
Static method to validate whether the given branchid and chainage values
match the expectation of a new structure.
Args:
values (dict): Dictionary of values to be used to generate a structure.
Raises:
ValueError: When the value for branchid or chainage are not valid.
Returns:
bool: Result of valid branchid / chainage in dictionary.
"""
branchid = values.get("branchid", None)
if branchid is None:
return False
chainage = values.get("chainage", None)
if str_is_empty_or_none(branchid) or chainage is None:
raise ValueError(
"A valid value for branchId and chainage is required when branchId key is specified."
)
return True
validate_coordinates_in_model(values: dict) -> bool
staticmethod
¶
Static method to validate whether the given values match the expectations of a structure to define its coordinates.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
values |
dict |
Dictionary of values to be used to generate a structure. |
required |
Exceptions:
Type | Description |
---|---|
ValueError |
When the given coordinates is less than 2. |
ValueError |
When the given coordinates do not match in expected size. |
Returns:
Type | Description |
---|---|
bool |
Result of valid coordinates in dictionary. |
Source code in hydrolib/core/io/structure/models.py
@staticmethod
def validate_coordinates_in_model(values: dict) -> bool:
"""
Static method to validate whether the given values match the expectations
of a structure to define its coordinates.
Args:
values (dict): Dictionary of values to be used to generate a structure.
Raises:
ValueError: When the given coordinates is less than 2.
ValueError: When the given coordinates do not match in expected size.
Returns:
bool: Result of valid coordinates in dictionary.
"""
searched_keys = ["numcoordinates", "xcoordinates", "ycoordinates"]
if any(values.get(k, None) is None for k in searched_keys):
return False
n_coords = values["numcoordinates"]
if n_coords < 2:
raise ValueError(
f"Expected at least 2 coordinates, but only {n_coords} declared."
)
def get_coord_len(coord: str) -> int:
if values[coord] is None:
return 0
return len(values[coord])
len_x_coords = get_coord_len("xcoordinates")
len_y_coords = get_coord_len("ycoordinates")
if n_coords == len_x_coords == len_y_coords:
return True
raise ValueError(
f"Expected {n_coords} coordinates, given {len_x_coords} for xCoordinates and {len_y_coords} for yCoordinates."
)
StructureGeneral (INIGeneral)
pydantic-model
¶
[General]
section with structure file metadata.
StructureModel (INIModel)
pydantic-model
¶
The overall structure model that contains the contents of one structure file.
This model is typically referenced under a FMModel.geometry.structurefile[..]
.
Attributes:
Name | Type | Description |
---|---|---|
general |
StructureGeneral |
|
branch |
List[Structure] |
List of |
UniversalWeir (Structure)
pydantic-model
¶
Hydraulic structure with type=universalWeir
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the universal weir input as described in UM Sec.C.12.2.
Weir (Structure)
pydantic-model
¶
Hydraulic structure with type=weir
, to be included in a structure file.
Typically inside the structure list of a FMModel.geometry.structurefile[0].structure[..]
All lowercased attributes match with the weir input as described in UM Sec.C.12.1.