Source code for glotaran.optimization.optimization_history

"""Module containing the ``OptimizationHistory`` class."""

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any

import pandas as pd

from glotaran.utils.regex import RegexPattern

if TYPE_CHECKING:
    from glotaran.typing import StrOrPath


[docs] class OptimizationHistory: """Wrapped DataFrame to hold information of the optimization and behaves like a ``DataFrame``. Ref.: https://stackoverflow.com/a/65375904/3990615 """ def __init__(self, data=None, source_path: StrOrPath | None = None) -> None: """Ensure DataFrame has the correct columns, is numeric and has iteration as index.""" self._df = ( pd.DataFrame( data, columns=["iteration", "nfev", "cost", "cost_reduction", "step_norm", "optimality"], ) .apply(pd.to_numeric) .set_index("iteration") ) if source_path is not None: self.source_path = Path(source_path).as_posix() else: self.source_path = "optimization_history.csv" def __getattr__(self, attr: str) -> Any: """Access class attribute and fallback to DataFrame attribute if not present. Parameters ---------- attr: str Name of the attribute to access. Returns ------- Any Attribute of ``OptimizationHistory`` or the DataFrame """ if attr in self.__dict__: return getattr(self, attr) return getattr(self.data, attr) def __getitem__(self, column: str) -> pd.Series: """Access DataFrame instead of class items. Parameters ---------- column: str Name of the column to access. Returns ------- pd.Series Column of the DataFrame. """ return self.data[column] @property def data(self) -> pd.DataFrame: """Underlying ``DataFrame`` which allows for autocomplete with static analyzers. Returns ------- pd.DataFrame ``DataFrame`` containing ``OptimizationHistory`` data. """ return self._df
[docs] @classmethod def from_stdout_str( cls: type[OptimizationHistory], optimize_stdout: str ) -> OptimizationHistory: """Create ``OptimizationHistory`` instance from ``optimize_stdout``. Parameters ---------- optimize_stdout: str SciPy optimization stdout string, read out via ``TeeContext.read()``. Returns ------- OptimizationHistory ``OptimizationHistory`` instance created by parsing ``optimize_stdout``. """ return cls( [m.groupdict() for m in RegexPattern.optimization_stdout.finditer(optimize_stdout)] )
[docs] @classmethod def from_csv(cls: type[OptimizationHistory], path: StrOrPath) -> OptimizationHistory: """Read ``OptimizationHistory`` from file. Parameters ---------- path : StrOrPath The path to the csv file. Returns ------- OptimizationHistory ``OptimizationHistory`` read from file. """ return cls(pd.read_csv(path), source_path=Path(path).as_posix())
loader = from_csv
[docs] def to_csv(self, path: StrOrPath, delimiter: str = ","): """Write a ``OptimizationHistory`` to a CSV file and set ``source_path``. Parameters ---------- path : StrOrPath The path to the CSV file. delimiter : str The delimiter of the CSV file. """ self.source_path = Path(path).as_posix() self.data.to_csv(path, sep=delimiter)