Source code for ogstools.core.result

# SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
# SPDX-License-Identifier: BSD-3-Clause

import filecmp
from pathlib import Path

from .storage import StorageBase


[docs] class Result(StorageBase): """ Container for OGS simulation results and output files. Manages the simulation output directory containing result files (meshes, logs, etc.) and provides access to simulation outputs. """ __hash__ = None
[docs] def __init__( self, sim_output: Path | str | None = None, ) -> None: """ Initialize a Result object. :param sim_output: Path to the simulation output directory. If None, uses a default location. """ super().__init__("Result") if sim_output: self._bind_to_path(sim_output) self._log_filename = "log.txt" self.next_target.mkdir(parents=True, exist_ok=True)
@property def sim_output(self) -> Path: """Get the path to the simulation output directory.""" return self.active_target or self.next_target @property def log_file(self) -> Path: """Get the path to the log file, following the current target location.""" return self.sim_output / self._log_filename def _save_impl(self, dry_run: bool = False) -> list[Path]: target = self.next_target if not dry_run: target.parent.mkdir(parents=True, exist_ok=True) if self.active_target and target != self.active_target: target.symlink_to(self.active_target, target_is_directory=True) # Return the target directory that was created/linked return [self.next_target] def _propagate_target(self) -> None: pass def __eq__(self, other: object) -> bool: if not isinstance(other, Result): return False return ( filecmp.dircmp(self.sim_output, other.sim_output).diff_files == [] )
[docs] def save( self, target: Path | str | None = None, overwrite: bool | None = None, dry_run: bool = False, archive: bool = False, id: str | None = None, ) -> list[Path]: """ Save or link the result output directory. Creates a symlink to the actual simulation output directory at the target location. Use archive=True to copy all data instead. :param target: Path where the result should be saved/linked. If None, uses a default location. :param overwrite: If True, overwrite existing target. Defaults to False. :param dry_run: If True, simulate save without creating files. :param archive: If True, copy all data instead of creating symlinks. :param id: Optional identifier. Mutually exclusive with target. :returns: List of Paths to created files/directories. """ user_defined = self._pre_save(target, overwrite, dry_run, id=id) files = self._save_impl(dry_run=dry_run) self._post_save(user_defined, archive, dry_run) return files
def __repr__(self) -> str: cls_name = self.__class__.__name__ base_repr = super().__repr__() output_str = self.active_target if self.is_saved else self.sim_output construct = f"{cls_name}(sim_output={str(output_str)!r})" return f"{construct}\n{base_repr}" def __str__(self) -> str: base_str = super().__str__() lines = [base_str] lines.append(f" - sim_output: {self._format_path(self.sim_output)}") lines.append(f" - log_file: {self._format_path(self.log_file)}") return "\n".join(lines)