Skip to content

Sample files

Sample .xyz files contain spatial input point data for a D-Flow FM model, and are used in various other input files.

A sample data file is described by the classes below.

Model

XYZModel (ParsableFileModel) pydantic-model

Sample or forcing file.

Attributes:

Name Type Description
points List[hydrolib.core.dflowfm.xyz.models.XYZPoint]

List of XYZPoint

dict(self, *args, **kwargs)

Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.

Source code in hydrolib/core/dflowfm/xyz/models.py
def dict(self, *args, **kwargs):
    # speed up serializing by not converting these lowest models to dict
    return dict(points=self.points)

XYZPoint (BaseModel) pydantic-model

Single sample or forcing point.

Attributes:

Name Type Description
x float

x or λ coordinate

y float

y or φ coordinate

z float

sample value or group number (forcing)

comment Optional[str]

keyword for grouping (forcing)

comment: str pydantic-field

comment or group name

Parser

XYZParser

A parser for .xyz files which are like this:

number number number number number number # comment

Note that the whitespace can vary and the comment left out.

parse(filepath: Path) -> Dict staticmethod

Parse an .xyz file into a Dict with the list of points read.

Parameters:

Name Type Description Default
filepath Path

.xyz file to be read.

required

Returns:

Type Description
Dict

dictionary with "points" value set to a list of points each of which is a dict itself, with keys 'x', 'y', 'z' and 'c' for an optional comment.

Exceptions:

Type Description
ValueError

if a line in the file contains no values that could be parsed.

Source code in hydrolib/core/dflowfm/xyz/parser.py
@staticmethod
def parse(filepath: Path) -> Dict:
    """Parse an .xyz file into a Dict with the list of points read.

    Args:
        filepath (Path): .xyz file to be read.

    Returns:
        Dict: dictionary with "points" value set to a list of points
            each of which is a dict itself, with keys 'x', 'y', 'z'
            and 'c' for an optional comment.

    Raises:
        ValueError: if a line in the file contains no values that
            could be parsed.
    """

    data: Dict = dict(points=[])

    with filepath.open(encoding="utf8") as f:
        for linenr, line in enumerate(f.readlines()):

            line = line.strip()
            if line.startswith("*") or len(line) == 0:
                continue

            try:
                x, y, z, *c = re.split(xyzpattern, line, maxsplit=3)
            except ValueError:
                raise ValueError(
                    f"Error parsing XYZ file '{filepath}', line {linenr+1}."
                )

            c = c[0] if len(c) > 0 else ""
            c = c.strip("#").strip()
            if len(c) == 0:
                c = None

            data["points"].append(dict(x=x, y=y, z=z, comment=c))

    return data

Serializer

XYZSerializer

serialize(path: Path, data: Dict, config: SerializerConfig, save_settings: ModelSaveSettings) -> None staticmethod

Serializes the XYZ data to the file at the specified path.

Attributes:

Name Type Description
path Path

The path to the destination file.

data Dict

The data to be serialized.

config SerializerConfig

The serialization configuration.

save_settings ModelSaveSettings

The model save settings.

Source code in hydrolib/core/dflowfm/xyz/serializer.py
@staticmethod
def serialize(
    path: Path,
    data: Dict,
    config: SerializerConfig,
    save_settings: ModelSaveSettings,
) -> None:
    """
    Serializes the XYZ data to the file at the specified path.

    Attributes:
        path (Path): The path to the destination file.
        data (Dict): The data to be serialized.
        config (SerializerConfig): The serialization configuration.
        save_settings (ModelSaveSettings): The model save settings.
    """
    path.parent.mkdir(parents=True, exist_ok=True)

    space = 1 * " "
    format_float = lambda x: f"{x:{config.float_format}}"

    with path.open("w", encoding="utf8") as f:
        for point in data["points"]:
            geometry: str = space.join(
                [format_float(p) for p in XYZSerializer._get_point_values(point)]
            )
            if point.comment:
                f.write(f"{geometry} # {point.comment}\n")
            else:
                f.write(f"{geometry}\n")
Back to top