Source code for cfdmod.geometry.grouping.io

"""Serialization helpers for grouping chains.

The existing :func:`cfdmod.io.write_processing_metadata` takes a generic
``config: dict`` which it serializes to YAML inside the HDF5 file. To
record a grouping chain, callers pass ``{"groupings": [spec.model_dump()
for spec in chain]}`` (alongside ``"filters"``, etc.). The helpers in
this module wrap that idiom so call sites stay legible:

    write_processing_metadata(h5, "/", {"groupings": dump_groupings(chain)})

    md = read_processing_metadata(h5, "/")
    chain = load_groupings(md["config"]["groupings"])

Round-trip: ``load_groupings(dump_groupings(chain)) == chain`` for any
valid chain.
"""

from __future__ import annotations

from typing import Any

from pydantic import TypeAdapter

from cfdmod.geometry.grouping.specs import GroupingSpec

_GROUPING_LIST_ADAPTER = TypeAdapter(list[GroupingSpec])


[docs] def dump_groupings(groupings: list[GroupingSpec]) -> list[dict[str, Any]]: """Serialize a chain of grouping specs to plain dicts (YAML/JSON-safe). Each entry retains its ``kind`` discriminator so :func:`load_groupings` can route it back to the correct spec class. Args: groupings: Chain of validated spec instances. Returns: ``list[dict]`` suitable for ``write_processing_metadata`` or any YAML/JSON serializer. """ return [spec.model_dump(mode="python") for spec in groupings]
[docs] def load_groupings(serialized: list[dict[str, Any]]) -> list[GroupingSpec]: """Re-hydrate a chain of grouping specs from their dict form. Uses the ``GroupingSpec`` discriminated union, so each entry must carry a ``kind`` key matching one of the registered spec classes. Args: serialized: Output of :func:`dump_groupings` (or any list of dicts with a valid ``kind`` discriminator). Returns: Validated spec instances ready to feed to :func:`cfdmod.geometry.grouping.apply_groupings`. Raises: pydantic.ValidationError: If any entry is not a valid spec. """ return _GROUPING_LIST_ADAPTER.validate_python(serialized)