Skip to content

Initial and parameter field files

The inifield file contains the initial conditions and spatial parameter input fields for a D-Flow FM model.

Generic parsing and serializing functionality comes from the generic hydrolib.core.dflowfm.ini modules.

The inifield file is represented by the classes below.

Model

Initial field model definitions for D-Flow FM inifield files.

AbstractSpatialField

Bases: INIBasedModel, ABC

Abstract base class for [Initial] and [Parameter] block data in inifield files.

Defines all common fields. Used via subclasses InitialField and ParameterField.

Source code in hydrolib/core/dflowfm/inifield/models.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
class AbstractSpatialField(INIBasedModel, ABC):
    """Abstract base class for `[Initial]` and `[Parameter]` block data in inifield files.

    Defines all common fields. Used via subclasses InitialField and ParameterField.
    """

    class Comments(INIBasedModel.Comments):
        """Comments for the AbstractSpatialField section fields."""

        quantity: Optional[str] = Field(
            "Name of the quantity. See UM Table D.2.", alias="quantity"
        )
        datafile: Optional[str] = Field(
            "Name of file containing field data values.", alias="dataFile"
        )
        datafiletype: Optional[str] = Field("Type of dataFile.", alias="dataFileType")
        interpolationmethod: Optional[str] = Field(
            "Type of (spatial) interpolation.", alias="interpolationmethod"
        )
        operand: Optional[str] = Field(
            "How this data is combined with previous data for the same quantity (if any).",
            alias="operand",
        )
        averagingtype: Optional[str] = Field(
            "Type of averaging, if interpolationMethod=averaging .",
            alias="averagingtype",
        )
        averagingrelsize: Optional[str] = Field(
            "Relative search cell size for averaging.", alias="averagingrelsize"
        )
        averagingnummin: Optional[str] = Field(
            "Minimum number of points in averaging. Must be ≥ 1.",
            alias="averagingnummin",
        )
        averagingpercentile: Optional[str] = Field(
            "Percentile value for which data values to include in averaging. 0.0 means off.",
            alias="averagingpercentile",
        )
        extrapolationmethod: Optional[str] = Field(
            "Option for (spatial) extrapolation.", alias="extrapolationmethod"
        )
        locationtype: Optional[str] = Field(
            "Target location of interpolation.", alias="locationtype"
        )
        value: Optional[str] = Field(
            "Only for dataFileType=polygon. The constant value to be set inside for all model points inside the polygon."
        )

    comments: Comments = Comments()

    quantity: str = Field(alias="quantity")
    datafile: DiskOnlyFileModel = Field(alias="dataFile")

    datafiletype: DataFileType = Field(alias="dataFileType")
    interpolationmethod: Optional[InterpolationMethod] = Field(
        None, alias="interpolationMethod"
    )
    operand: Optional[Operand] = Field(Operand.override.value, alias="operand")
    averagingtype: Optional[AveragingType] = Field(None, alias="averagingType")
    averagingrelsize: Optional[NonNegativeFloat] = Field(None, alias="averagingRelSize")
    averagingnummin: Optional[PositiveInt] = Field(None, alias="averagingNumMin")
    averagingpercentile: Optional[NonNegativeFloat] = Field(
        None, alias="averagingPercentile"
    )
    extrapolationmethod: Optional[bool] = Field(False, alias="extrapolationMethod")
    locationtype: Optional[LocationType] = Field(
        LocationType.all.value, alias="locationType"
    )
    value: Optional[float] = Field(None, alias="value")

    model_config = ConfigDict(extra="allow")

    @classmethod
    def _process_section_values(cls, values):
        """Process Section objects and extract/convert values as needed.

        Args:
            values: The values to process, which may be a Section object or a dictionary.

        Returns:
            A dictionary containing the processed values.
        """
        # If values is a Section object, we need to handle it specially
        if isinstance(values, Section):
            # Extract the datafile value if present
            data_file = super()._extract_file_model_from_section(
                values, "datafile", DiskOnlyFileModel
            )

            # Convert Section to dictionary
            values_dict = super()._convert_section_to_dict(values)

            # If we found a datafile, add it to the dictionary
            if data_file is not None:
                values_dict["datafile"] = data_file

            return values_dict

        return values

    tracerfallvelocity: Optional[float] = Field(None, alias="tracerFallVelocity")
    tracerdecaytime: Optional[float] = Field(None, alias="tracerDecayTime")

    @model_validator(mode="before")
    @classmethod
    def validate_that_value_is_present_for_polygons(cls, values: Dict) -> Dict:
        """Validates that the value is provided when dealing with polygons."""
        # Process Section objects if needed
        values = cls._process_section_values(values)

        # Process dictionary-like objects
        data_file = values.get("datafile")
        if isinstance(data_file, (str, Path)):
            data_file = DiskOnlyFileModel(data_file)
            values["datafile"] = data_file

        validate_required_fields(
            values,
            "value",
            conditional_field_name="datafiletype",
            conditional_value=DataFileType.polygon,
        )

        value_field_value = values.get("value")
        datafiletype_field_value = values.get("datafiletype")
        if (
            value_field_value is not None
            and datafiletype_field_value is not None
            and datafiletype_field_value.lower() != DataFileType.polygon
        ):
            raise ValueError(
                f"When value={value_field_value} is given, dataFileType={DataFileType.polygon} is required."
            )

        return values

    @field_validator("locationtype", mode="before")
    @classmethod
    def validate_location_type(cls, v):
        return enum_value_parser(v, LocationType)

    @field_validator("averagingtype", mode="before")
    @classmethod
    def validate_average_type(cls, v):
        return enum_value_parser(v, AveragingType)

    @field_validator("datafiletype", mode="before")
    @classmethod
    def validate_data_file_type(cls, v):
        return enum_value_parser(v, DataFileType)

    @field_validator("operand", mode="before")
    @classmethod
    def validate_operand(cls, v):
        return enum_value_parser(v, Operand)

    @field_validator("interpolationmethod", mode="before")
    @classmethod
    def validate_interpolation_method(cls, v):
        return enum_value_parser(v, InterpolationMethod)

    @field_validator("datafile", mode="before")
    @classmethod
    def validate_datafile(cls, v):
        """Convert string values to DiskOnlyFileModel instances."""
        if isinstance(v, (str, Path)):
            return DiskOnlyFileModel(filepath=v)
        return v

Comments

Bases: Comments

Comments for the AbstractSpatialField section fields.

Source code in hydrolib/core/dflowfm/inifield/models.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
class Comments(INIBasedModel.Comments):
    """Comments for the AbstractSpatialField section fields."""

    quantity: Optional[str] = Field(
        "Name of the quantity. See UM Table D.2.", alias="quantity"
    )
    datafile: Optional[str] = Field(
        "Name of file containing field data values.", alias="dataFile"
    )
    datafiletype: Optional[str] = Field("Type of dataFile.", alias="dataFileType")
    interpolationmethod: Optional[str] = Field(
        "Type of (spatial) interpolation.", alias="interpolationmethod"
    )
    operand: Optional[str] = Field(
        "How this data is combined with previous data for the same quantity (if any).",
        alias="operand",
    )
    averagingtype: Optional[str] = Field(
        "Type of averaging, if interpolationMethod=averaging .",
        alias="averagingtype",
    )
    averagingrelsize: Optional[str] = Field(
        "Relative search cell size for averaging.", alias="averagingrelsize"
    )
    averagingnummin: Optional[str] = Field(
        "Minimum number of points in averaging. Must be ≥ 1.",
        alias="averagingnummin",
    )
    averagingpercentile: Optional[str] = Field(
        "Percentile value for which data values to include in averaging. 0.0 means off.",
        alias="averagingpercentile",
    )
    extrapolationmethod: Optional[str] = Field(
        "Option for (spatial) extrapolation.", alias="extrapolationmethod"
    )
    locationtype: Optional[str] = Field(
        "Target location of interpolation.", alias="locationtype"
    )
    value: Optional[str] = Field(
        "Only for dataFileType=polygon. The constant value to be set inside for all model points inside the polygon."
    )

validate_datafile(v) classmethod

Convert string values to DiskOnlyFileModel instances.

Source code in hydrolib/core/dflowfm/inifield/models.py
266
267
268
269
270
271
272
@field_validator("datafile", mode="before")
@classmethod
def validate_datafile(cls, v):
    """Convert string values to DiskOnlyFileModel instances."""
    if isinstance(v, (str, Path)):
        return DiskOnlyFileModel(filepath=v)
    return v

validate_that_value_is_present_for_polygons(values) classmethod

Validates that the value is provided when dealing with polygons.

Source code in hydrolib/core/dflowfm/inifield/models.py
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
@model_validator(mode="before")
@classmethod
def validate_that_value_is_present_for_polygons(cls, values: Dict) -> Dict:
    """Validates that the value is provided when dealing with polygons."""
    # Process Section objects if needed
    values = cls._process_section_values(values)

    # Process dictionary-like objects
    data_file = values.get("datafile")
    if isinstance(data_file, (str, Path)):
        data_file = DiskOnlyFileModel(data_file)
        values["datafile"] = data_file

    validate_required_fields(
        values,
        "value",
        conditional_field_name="datafiletype",
        conditional_value=DataFileType.polygon,
    )

    value_field_value = values.get("value")
    datafiletype_field_value = values.get("datafiletype")
    if (
        value_field_value is not None
        and datafiletype_field_value is not None
        and datafiletype_field_value.lower() != DataFileType.polygon
    ):
        raise ValueError(
            f"When value={value_field_value} is given, dataFileType={DataFileType.polygon} is required."
        )

    return values

AveragingType

Bases: StrEnum

Enum class containing the valid values for the averagingType attribute.

Contains valid values for the averagingType attribute in several subclasses of AbstractIniField.

Source code in hydrolib/core/dflowfm/inifield/models.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class AveragingType(StrEnum):
    """Enum class containing the valid values for the averagingType attribute.

    Contains valid values for the averagingType attribute in several subclasses
    of AbstractIniField.
    """

    mean = "mean"  # simple average
    nearestnb = "nearestNb"  # nearest neighbour value
    max = "max"  # highest
    min = "min"  # lowest
    invdist = "invDist"  # inverse-weighted distance average
    minabs = "minAbs"  # smallest absolute value
    median = "median"

    allowedvaluestext = (
        "Possible values: mean, nearestNb, max, min, invDist, minAbs, median."
    )

DataFileType

Bases: StrEnum

Enum class containing the valid values for the dataFileType attribute.

Contains valid values for the dataFileType attribute in several subclasses of AbstractIniField.

Source code in hydrolib/core/dflowfm/inifield/models.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class DataFileType(StrEnum):
    """Enum class containing the valid values for the dataFileType attribute.

    Contains valid values for the dataFileType attribute in several subclasses
    of AbstractIniField.
    """

    arcinfo = "arcinfo"
    geotiff = "GeoTIFF"
    sample = "sample"
    onedfield = "1dField"
    polygon = "polygon"
    uniform = "uniform"
    netcdf = "netcdf"

    allowedvaluestext = "Possible values: arcinfo, GeoTIFF, sample, 1dField, polygon."

IniFieldGeneral

Bases: INIGeneral

The initial field file's [General] section with file meta data.

Source code in hydrolib/core/dflowfm/inifield/models.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
class IniFieldGeneral(INIGeneral):
    """The initial field file's `[General]` section with file meta data."""

    class Comments(INIBasedModel.Comments):
        """Comments for the IniFieldGeneral section fields."""

        fileversion: Optional[str] = Field(
            "File version. Do not edit this.", alias="fileVersion"
        )
        filetype: Optional[str] = Field(
            "File type. Should be 'iniField'. Do not edit this.",
            alias="fileType",
        )

    comments: Comments = Comments()
    _header: Literal["General"] = "General"
    fileversion: str = Field("2.00", alias="fileVersion")
    filetype: Literal["iniField"] = Field("iniField", alias="fileType")

Comments

Bases: Comments

Comments for the IniFieldGeneral section fields.

Source code in hydrolib/core/dflowfm/inifield/models.py
88
89
90
91
92
93
94
95
96
97
class Comments(INIBasedModel.Comments):
    """Comments for the IniFieldGeneral section fields."""

    fileversion: Optional[str] = Field(
        "File version. Do not edit this.", alias="fileVersion"
    )
    filetype: Optional[str] = Field(
        "File type. Should be 'iniField'. Do not edit this.",
        alias="fileType",
    )

IniFieldModel

Bases: INIModel

The overall inifield model that contains the contents of one initial field and parameter file.

This model is typically referenced under a FMModel.geometry.inifieldfile[..].

Attributes:

Name Type Description
general IniFieldGeneral

[General] block with file metadata.

initial List[InitialField]

List of [Initial] blocks with initial condition definitions.

parameter List[ParameterField]

List of [Parameter] blocks with spatial parameter definitions.

Source code in hydrolib/core/dflowfm/inifield/models.py
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
class IniFieldModel(INIModel):
    """
    The overall inifield model that contains the contents of one initial field and parameter file.

    This model is typically referenced under a [FMModel][hydrolib.core.dflowfm.mdu.models.FMModel]`.geometry.inifieldfile[..]`.

    Attributes:
        general (IniFieldGeneral): `[General]` block with file metadata.
        initial (List[InitialField]): List of `[Initial]` blocks with initial condition definitions.
        parameter (List[ParameterField]): List of `[Parameter]` blocks with spatial parameter definitions.
    """

    general: IniFieldGeneral = IniFieldGeneral()
    initial: Annotated[List[InitialField], BeforeValidator(make_list)] = Field(
        default_factory=list
    )
    parameter: Annotated[List[ParameterField], BeforeValidator(make_list)] = Field(
        default_factory=list
    )

    @classmethod
    def _ext(cls) -> str:
        return ".ini"

    @classmethod
    def _filename(cls) -> str:
        return "fieldFile"

InitialField

Bases: AbstractSpatialField

Initial condition field definition, represents an [Initial] block in an inifield file.

Typically inside the definition list of a FMModel.geometry.inifieldfile.initial[..]

All lowercased attributes match with the initial field input as described in UM Sec.D.2.

Source code in hydrolib/core/dflowfm/inifield/models.py
275
276
277
278
279
280
281
282
283
284
285
class InitialField(AbstractSpatialField):
    """Initial condition field definition, represents an `[Initial]` block in an inifield file.

    Typically inside the definition list of a
    [FMModel][hydrolib.core.dflowfm.mdu.models.FMModel]`.geometry.inifieldfile.initial[..]`

    All lowercased attributes match with the initial field input as described in
    [UM Sec.D.2](https://content.oss.deltares.nl/delft3dfm1d2d/D-Flow_FM_User_Manual_1D2D.pdf#subsection.D.2).
    """

    _header: Literal["Initial"] = "Initial"

InterpolationMethod

Bases: StrEnum

Enum class containing the valid values for the interpolationMethod attribute.

Contains valid values for the interpolationMethod attribute in several subclasses of AbstractIniField.

Source code in hydrolib/core/dflowfm/inifield/models.py
50
51
52
53
54
55
56
57
58
59
60
61
62
class InterpolationMethod(StrEnum):
    """Enum class containing the valid values for the interpolationMethod attribute.

    Contains valid values for the interpolationMethod attribute in several
    subclasses of AbstractIniField.
    """

    constant = "constant"  # only with dataFileType=polygon .
    triangulation = "triangulation"  # Delaunay triangulation+linear interpolation.
    averaging = "averaging"  # grid cell averaging.
    linear_space_time = "linearSpaceTime"  # linear interpolation in space and time.

    allowedvaluestext = "Possible values: constant, triangulation, averaging."

ParameterField

Bases: AbstractSpatialField

Parameter field definition, represents a [Parameter] block in an inifield file.

Typically inside the definition list of a FMModel.geometry.inifieldfile.parameter[..]

Source code in hydrolib/core/dflowfm/inifield/models.py
288
289
290
291
292
293
294
295
class ParameterField(AbstractSpatialField):
    """Parameter field definition, represents a `[Parameter]` block in an inifield file.

    Typically inside the definition list of a
    [FMModel][hydrolib.core.dflowfm.mdu.models.FMModel]`.geometry.inifieldfile.parameter[..]`
    """

    _header: Literal["Parameter"] = "Parameter"