Skip to content

Observation point files

Observation point files come in two flavours:

Observation point .ini files

The obs module provides the specific logic for accessing observation point .ini files for a D-Flow FM model.

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

An observation point .ini file is described by the classes below.

Model

ObservationPoint

Bases: INIBasedModel

An observation point that is included in the observation point file.

All lowercased attributes match with the observation point input as described in UM Sec.F.2.2.1.

Source code in hydrolib/core/dflowfm/obs/models.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class ObservationPoint(INIBasedModel):
    """
    An observation point that is included in the observation point file.

    All lowercased attributes match with the observation point input as described in
    [UM Sec.F.2.2.1](https://content.oss.deltares.nl/delft3dfm1d2d/D-Flow_FM_User_Manual_1D2D.pdf#subsubsection.F.2.2.1).
    """

    class Comments(INIBasedModel.Comments):
        name: Optional[str] = "Name of the observation point (max. 255 characters)."
        locationtype: Optional[str] = (
            "Only when x and y are also specified. 1d: snap to closest 1D grid point, 2d: snap to closest 2D grid cell centre, all: snap to closest 1D or 2D point."
        )
        branchid: Optional[str] = Field(
            "Branch on which the observation point is located.", alias="branchId"
        )
        chainage: Optional[str] = "Chainage on the branch (m)."

        x: Optional[str] = Field(
            "x-coordinate of the location of the observation point.",
            alias="x",
        )
        y: Optional[str] = Field(
            "y-coordinate of the location of the observation point.",
            alias="y",
        )

    comments: Comments = Comments()

    _header: Literal["ObservationPoint"] = "ObservationPoint"

    name: str = Field("id", max_length=255, alias="name")
    locationtype: Optional[LocationType] = Field(None, alias="locationType")

    branchid: Optional[str] = Field(None, alias="branchId")
    chainage: Optional[float] = Field(None, alias="chainage")

    x: Optional[float] = Field(None, alias="x")
    y: Optional[float] = Field(None, alias="y")

    _type_validator = get_enum_validator("locationtype", enum=LocationType)

    @root_validator(allow_reuse=True)
    def validate_that_location_specification_is_correct(cls, values: Dict) -> Dict:
        """Validates that the correct location specification is given."""
        return validate_location_specification(
            values,
            config=LocationValidationConfiguration(
                validate_node=False, validate_num_coordinates=False
            ),
            fields=LocationValidationFieldNames(x_coordinates="x", y_coordinates="y"),
        )

    def _get_identifier(self, data: dict) -> Optional[str]:
        return data.get("name")

validate_that_location_specification_is_correct(values)

Validates that the correct location specification is given.

Source code in hydrolib/core/dflowfm/obs/models.py
77
78
79
80
81
82
83
84
85
86
@root_validator(allow_reuse=True)
def validate_that_location_specification_is_correct(cls, values: Dict) -> Dict:
    """Validates that the correct location specification is given."""
    return validate_location_specification(
        values,
        config=LocationValidationConfiguration(
            validate_node=False, validate_num_coordinates=False
        ),
        fields=LocationValidationFieldNames(x_coordinates="x", y_coordinates="y"),
    )

ObservationPointGeneral

Bases: INIGeneral

The observation point file's [General] section with file meta data.

Source code in hydrolib/core/dflowfm/obs/models.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class ObservationPointGeneral(INIGeneral):
    """The observation point file's `[General]` section with file meta data."""

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

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

ObservationPointModel

Bases: INIModel

The overall observation point model that contains the contents of one observation point file.

This model is typically referenced under a FMModel.output.obsfile[..].

Attributes:

Name Type Description
general ObservationPointGeneral

[General] block with file metadata.

observationpoint List[ObservationPoint]

List of [ObservationPoint] blocks for all observation points.

Source code in hydrolib/core/dflowfm/obs/models.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
class ObservationPointModel(INIModel):
    """
    The overall observation point model that contains the contents of one observation point file.

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

    Attributes:
        general (ObservationPointGeneral): `[General]` block with file metadata.
        observationpoint (List[ObservationPoint]): List of `[ObservationPoint]` blocks for all observation points.
    """

    general: ObservationPointGeneral = ObservationPointGeneral()
    observationpoint: List[ObservationPoint] = []

    _make_list = make_list_validator("observationpoint")

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

Legacy observation point .xyn files

The xyn module provides the specific logic for accessing legacy observation point files for a D-Flow FM model.

An observation point .xyn file is described by the classes below.

Model

XYNModel

Bases: ParsableFileModel

Observation station (.xyn) file.

Source code in hydrolib/core/dflowfm/xyn/models.py
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
class XYNModel(ParsableFileModel):
    """Observation station (.xyn) file."""

    points: List[XYNPoint] = []
    """List[`XYNPoint`]: List of XYN points."""

    def dict(self, *args, **kwargs):
        # speed up serializing by not converting these lowest models to dict
        return dict(points=self.points)

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

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

    @classmethod
    def _get_serializer(
        cls,
    ) -> Callable[[Path, Dict, SerializerConfig, ModelSaveSettings], None]:
        return XYNSerializer.serialize

    @classmethod
    def _get_parser(cls) -> Callable[[Path], Dict]:
        return XYNParser.parse

points = [] class-attribute instance-attribute

List[XYNPoint]: List of XYN points.

XYNPoint

Bases: BaseModel

Single XYN point, representing a named station location.

Source code in hydrolib/core/dflowfm/xyn/models.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class XYNPoint(BaseModel):
    """Single XYN point, representing a named station location."""

    x: float
    """float: The x or λ coordinate."""

    y: float
    """float: The y or φ coordinate."""

    n: str
    """float: The name of the point."""

    def _get_identifier(self, data: dict) -> Optional[str]:
        x = data.get("x")
        y = data.get("y")
        n = data.get("n")
        return f"x:{x} y:{y} n:{n}"

    @validator("n", pre=True)
    def _validate_name(cls, value):
        if str_is_empty_or_none(value):
            raise ValueError("Name cannot be empty.")

        if "'" in value or '"' in value:
            raise ValueError(
                "Name cannot contain single or double quotes except at the start and end."
            )

        return value

n instance-attribute

float: The name of the point.

x instance-attribute

float: The x or λ coordinate.

y instance-attribute

float: The y or φ coordinate.