Skip to content

liblaf.melon.io ¤

Modules:

  • abc
  • paraview
  • pyvista
  • trimesh
  • warp
  • wrap

Classes:

  • PVDWriter

    .

  • SeriesReader
  • SeriesWriter

Functions:

  • as_mesh
  • get_landmarks_path
  • get_polygons_path
  • load_landmarks
  • load_polygons
  • save_landmarks
  • save_polygons

Attributes:

  • as_multi_block (ConverterDispatcher[MultiBlock]) –
  • as_pointset (ConverterDispatcher[PointSet]) –
  • as_polydata (ConverterDispatcher[PolyData]) –
  • as_structured_grid (ConverterDispatcher[StructuredGrid]) –
  • as_trimesh (ConverterDispatcher[Trimesh]) –
  • as_unstructured_grid (ConverterDispatcher[UnstructuredGrid]) –
  • as_warp_mesh (ConverterDispatcher[Mesh]) –
  • load_multi_block (ReaderDispatcher[MultiBlock]) –
  • load_polydata (ReaderDispatcher[PolyData]) –
  • load_structured_grid (ReaderDispatcher[StructuredGrid]) –
  • load_trimesh (ReaderDispatcher[Trimesh]) –
  • load_unstructured_grid (ReaderDispatcher[UnstructuredGrid]) –
  • save

as_multi_block module-attribute ¤

as_multi_block: ConverterDispatcher[MultiBlock] = (
    ConverterDispatcher(MultiBlock)
)

as_pointset module-attribute ¤

as_pointset: ConverterDispatcher[PointSet] = (
    ConverterDispatcher(PointSet)
)

as_polydata module-attribute ¤

as_polydata: ConverterDispatcher[PolyData] = (
    ConverterDispatcher(PolyData)
)

as_structured_grid module-attribute ¤

as_structured_grid: ConverterDispatcher[StructuredGrid] = (
    ConverterDispatcher(StructuredGrid)
)

as_trimesh module-attribute ¤

as_trimesh: ConverterDispatcher[Trimesh] = (
    ConverterDispatcher(Trimesh)
)

as_unstructured_grid module-attribute ¤

as_unstructured_grid: ConverterDispatcher[
    UnstructuredGrid
] = ConverterDispatcher(UnstructuredGrid)

as_warp_mesh module-attribute ¤

as_warp_mesh: ConverterDispatcher[Mesh] = (
    ConverterDispatcher(Mesh)
)

load_multi_block module-attribute ¤

load_multi_block: ReaderDispatcher[MultiBlock] = (
    ReaderDispatcher(MultiBlock)
)

load_polydata module-attribute ¤

load_polydata: ReaderDispatcher[PolyData] = (
    ReaderDispatcher(PolyData)
)

load_structured_grid module-attribute ¤

load_structured_grid: ReaderDispatcher[StructuredGrid] = (
    ReaderDispatcher(StructuredGrid)
)

load_trimesh module-attribute ¤

load_trimesh: ReaderDispatcher[Trimesh] = ReaderDispatcher(
    Trimesh
)

load_unstructured_grid module-attribute ¤

load_unstructured_grid: ReaderDispatcher[
    UnstructuredGrid
] = ReaderDispatcher(UnstructuredGrid)

save module-attribute ¤

save = WriterDispatcher()

PVDWriter ¤

.

References

[1]: ParaView/Data formats - KitwarePublic

Parameters:

  • clear ¤

    (bool, default: False ) –
  • file ¤

    (Path, default: PosixPath('animation.pvd') ) –
  • fps ¤

    (float, default: 30.0 ) –

Attributes:

  • datasets (list[PVDDataSet]) –

    Built-in mutable sequence.

    If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

Methods:

  • __attrs_post_init__
  • append
  • end

clear class-attribute instance-attribute ¤

clear: bool = field(default=False, kw_only=True)

datasets class-attribute instance-attribute ¤

datasets: list[PVDDataSet] = field(init=False, factory=list)

file class-attribute instance-attribute ¤

file: Path = field(
    default=Path("animation.pvd"), converter=Path
)

folder property ¤

folder: Path

fps class-attribute instance-attribute ¤

fps: float = field(default=30.0, kw_only=True)

name property ¤

name: str

__attrs_post_init__ ¤

__attrs_post_init__() -> None
Source code in src/liblaf/melon/io/paraview/_pvd_writer.py
39
40
41
def __attrs_post_init__(self) -> None:
    if self.clear:
        shutil.rmtree(self.folder, ignore_errors=True)

append ¤

append(
    dataset: Any,
    timestep: float | None = None,
    *,
    ext: str,
    part: int = 0,
) -> None
Source code in src/liblaf/melon/io/paraview/_pvd_writer.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
def append(
    self, dataset: Any, timestep: float | None = None, *, ext: str, part: int = 0
) -> None:
    if timestep is None:
        timestep = (
            self.datasets[-1].timestep + (1 / self.fps) if self.datasets else 0
        )
    frame_id: int = len(self.datasets)
    filename: str = f"{self.name}_{frame_id:06d}"
    filename += ext
    filepath: Path = self.folder / filename
    save(filepath, dataset)
    self.datasets.append(PVDDataSet(timestep=timestep, part=part, file=filepath))
    self.end()

end ¤

end() -> None
Source code in src/liblaf/melon/io/paraview/_pvd_writer.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def end(self) -> None:
    root = ElementTree.Element(
        "VTKFile", type="Collection", version="0.1", byte_order="LittleEndian"
    )
    collection: ElementTree.Element = ElementTree.SubElement(root, "Collection")
    root_dir: Path = self.file.absolute().parent
    for dataset in self.datasets:
        elem: ElementTree.Element = ElementTree.SubElement(collection, "DataSet")
        elem.set("timestep", str(dataset.timestep))
        elem.set("part", str(dataset.part))
        elem.set("file", dataset.file.absolute().relative_to(root_dir).as_posix())
    tree = ElementTree.ElementTree(root)
    ElementTree.indent(tree, space="  ")
    self.file.parent.mkdir(parents=True, exist_ok=True)
    tree.write(self.file, xml_declaration=True)

SeriesReader ¤

SeriesReader(file: StrPath, loader: Callable[[Path], T])

Bases: Sequence[T]


              flowchart TD
              liblaf.melon.io.SeriesReader[SeriesReader]

              

              click liblaf.melon.io.SeriesReader href "" "liblaf.melon.io.SeriesReader"
            

Parameters:

Methods:

  • __getitem__
  • __len__

Attributes:

Source code in src/liblaf/melon/io/paraview/series/_reader.py
24
25
26
def __init__(self, file: StrPath, loader: Callable[[Path], T]) -> None:
    file = Path(file)
    self.__attrs_init__(file=file, loader=loader)  # pyright: ignore[reportAttributeAccessIssue]

file instance-attribute ¤

file: Path

folder property ¤

folder: Path

loader instance-attribute ¤

loader: Callable[[Path], T]

series cached property ¤

series: Series

time_values property ¤

time_values: list[float]

__getitem__ ¤

__getitem__(index: int) -> T
__getitem__(index: slice) -> Sequence[T]
Source code in src/liblaf/melon/io/paraview/series/_reader.py
32
33
34
35
36
37
38
@override
def __getitem__(self, index: int | slice) -> T | Sequence[T]:
    __tracebackhide__ = True
    files: File | list[File] = self.series.files[index]
    if isinstance(files, File):
        return self.loader(self.folder / files.name)
    return [self.loader(self.folder / f.name) for f in files]

__len__ ¤

__len__() -> int
Source code in src/liblaf/melon/io/paraview/series/_reader.py
40
41
42
@override
def __len__(self) -> int:
    return len(self.series.files)

SeriesWriter ¤

SeriesWriter(
    file: StrPath,
    /,
    *,
    clear: bool = False,
    fps: float = 30.0,
    step: float | None = None,
)

Bases: Sequence[File], AbstractContextManager


              flowchart TD
              liblaf.melon.io.SeriesWriter[SeriesWriter]

              

              click liblaf.melon.io.SeriesWriter href "" "liblaf.melon.io.SeriesWriter"
            

Parameters:

Methods:

  • __enter__
  • __exit__
  • __getitem__
  • __len__
  • append
  • end
  • save
  • start

Attributes:

Source code in src/liblaf/melon/io/paraview/series/_writer.py
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(
    self,
    file: StrPath,
    /,
    *,
    clear: bool = False,
    fps: float = 30.0,
    step: float | None = None,
) -> None:
    if step is None:
        step = 1.0 / fps
    self.__attrs_init__(file=Path(file), series=Series(), step=step)  # pyright: ignore[reportAttributeAccessIssue]
    if clear:
        shutil.rmtree(self.folder, ignore_errors=True)

ext property ¤

ext: str

file instance-attribute ¤

file: Path

folder property ¤

folder: Path

fps property ¤

fps: float

name property ¤

name: str

series instance-attribute ¤

series: Series

step instance-attribute ¤

step: float

time property ¤

time: float

__enter__ ¤

__enter__() -> Self
Source code in src/liblaf/melon/io/paraview/series/_writer.py
66
67
68
def __enter__(self) -> Self:
    self.start()
    return self

__exit__ ¤

__exit__(
    exc_type: type[BaseException] | None,
    exc_value: BaseException | None,
    traceback: TracebackType | None,
) -> None
Source code in src/liblaf/melon/io/paraview/series/_writer.py
70
71
72
73
74
75
76
def __exit__(
    self,
    exc_type: type[BaseException] | None,
    exc_value: BaseException | None,
    traceback: types.TracebackType | None,
) -> None:
    self.end()

__getitem__ ¤

__getitem__(index: int) -> File
__getitem__(index: slice) -> list[File]
Source code in src/liblaf/melon/io/paraview/series/_writer.py
60
61
def __getitem__(self, index: int | slice) -> File | list[File]:
    return self.series.files[index]

__len__ ¤

__len__() -> int
Source code in src/liblaf/melon/io/paraview/series/_writer.py
63
64
def __len__(self) -> int:
    return len(self.series.files)

append ¤

append(
    data: Any,
    *,
    time: float | None = None,
    timestep: float | None = None,
) -> None
Source code in src/liblaf/melon/io/paraview/series/_writer.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def append(
    self, data: Any, *, time: float | None = None, timestep: float | None = None
) -> None:
    __tracebackhide__ = True
    filename: str = f"{self.name}_{len(self):06d}{self.ext}"
    filepath: Path = self.folder / filename
    save(filepath, data)
    if time is None:
        if timestep is None:
            timestep = self.step
        time = self.time + timestep
    self.series.files.append(
        File(name=filepath.relative_to(self.file.parent).as_posix(), time=time)
    )
    self.save()

end ¤

end() -> None
Source code in src/liblaf/melon/io/paraview/series/_writer.py
116
117
def end(self) -> None:
    self.save()

save ¤

save() -> None
Source code in src/liblaf/melon/io/paraview/series/_writer.py
119
120
121
122
def save(self) -> None:
    grapes.save(
        self.file, self.series, force_ext=".json", pydantic={"by_alias": True}
    )

start ¤

start() -> None
Source code in src/liblaf/melon/io/paraview/series/_writer.py
124
125
def start(self) -> None:
    pass

as_mesh ¤

as_mesh(mesh: Any) -> PolyData | UnstructuredGrid
Source code in src/liblaf/melon/io/pyvista/_convert.py
11
12
13
14
15
16
def as_mesh(mesh: Any) -> pv.PolyData | pv.UnstructuredGrid:
    try:
        return as_polydata(mesh)
    except UnsupportedConverterError:
        pass
    return as_unstructured_grid(mesh)

get_landmarks_path ¤

get_landmarks_path(path: str | PathLike[str]) -> Path
Source code in src/liblaf/melon/io/wrap/landmarks/_utils.py
5
6
7
8
9
def get_landmarks_path(path: str | os.PathLike[str]) -> Path:
    path: Path = Path(path)
    if path.suffix != ".json":
        return path.with_suffix(".landmarks.json")
    return path

get_polygons_path ¤

get_polygons_path(path: str | PathLike[str]) -> Path
Source code in src/liblaf/melon/io/wrap/polygons/_utils.py
5
6
7
8
9
def get_polygons_path(path: str | os.PathLike[str]) -> Path:
    path: Path = Path(path)
    if path.suffix != ".json":
        return path.with_suffix(".polygons.json")
    return path

load_landmarks ¤

load_landmarks(
    path: str | PathLike[str],
) -> Float[ndarray, "N 3"]
Source code in src/liblaf/melon/io/wrap/landmarks/_reader.py
12
13
14
15
16
17
def load_landmarks(path: str | os.PathLike[str]) -> Float[np.ndarray, "N 3"]:
    path: Path = get_landmarks_path(path)
    if not path.exists():
        return np.empty((0, 3), dtype=float)
    data: list[dict[str, float]] = grapes.load(path)
    return np.asarray([[p["x"], p["y"], p["z"]] for p in data])

load_polygons ¤

load_polygons(path: StrPath) -> Integer[ndarray, ' N']
Source code in src/liblaf/melon/io/wrap/polygons/_reader.py
17
18
19
20
def load_polygons(path: StrPath) -> Integer[np.ndarray, " N"]:
    path: Path = get_polygons_path(path)
    data: list[int] = grapes.load(path)
    return np.asarray(data)

save_landmarks ¤

save_landmarks(
    path: str | PathLike[str],
    points: Float[ArrayLike, "N 3"],
) -> None
Source code in src/liblaf/melon/io/wrap/landmarks/_writer.py
12
13
14
15
16
17
18
19
20
def save_landmarks(
    path: str | os.PathLike[str], points: Float[ArrayLike, "N 3"]
) -> None:
    path: Path = get_landmarks_path(path)
    points: Float[np.ndarray, "N 3"] = np.asarray(points)
    data: list[dict[str, float]] = [
        {"x": p[0], "y": p[1], "z": p[2]} for p in points.tolist()
    ]
    grapes.save(path, data)

save_polygons ¤

save_polygons(
    path: str | PathLike[str],
    polygons: Bool[ArrayLike, " N"]
    | Integer[ArrayLike, " N"],
) -> None
Source code in src/liblaf/melon/io/wrap/polygons/_writer.py
12
13
14
15
16
17
18
19
20
def save_polygons(
    path: str | os.PathLike[str],
    polygons: Bool[ArrayLike, " N"] | Integer[ArrayLike, " N"],
) -> None:
    path: Path = get_polygons_path(path)
    polygons = np.asarray(polygons)
    if np.isdtype(polygons.dtype, "bool"):
        polygons = np.flatnonzero(polygons)
    grapes.save(path, polygons.tolist())