Source code for kbkit.schema.activity_metadata

"""Containers for storing activity coefficient properties and their polynomial fit functions."""

from dataclasses import dataclass
from typing import Literal

import numpy as np


[docs] @dataclass class ActivityCoefficientResult: r""" Containor for activity coefficient results and derivatives. Stores polynomial functions if ``activity_integration_type`` is `polynomial` and evaluates function from :math:`x_i`: 0 :math:`\rightarrow` 1. Parameters ---------- mol: str Molecule name. x: np.ndarray Array of mole fractions for ``mol``. y: np.ndarray Array of values corresponding to ``x``. property_type: str Type of activity coefficient property. Tags result object with `derivative` or `integrated`. fn: Callable, optional Optional function that describes activity coefficients. Only if ``activity_integration_type`` is `polynomial`. """ mol: str x: np.ndarray y: np.ndarray property_type: Literal["derivative", "integrated"] fn: np.poly1d | None = None # instead of "fn" @property def x_eval(self): """np.ndarray: Values to evaluate function at.""" return np.arange(0, 1.01, 0.01) if isinstance(self.fn, np.poly1d) else None @property def y_eval(self): """np.ndarray: Result of the function evaluated at ``x_eval``.""" return self.fn(self.x_eval) if isinstance(self.fn, np.poly1d) else None @property def has_fn(self) -> bool: """bool: Check if a fit function is defined.""" return bool(self.fn)
[docs] @dataclass class ActivityMetadata: """ Container for collection of ActivityCoefficientResult objects. Parameters ---------- results: list[ActivityCoefficientResult] List of ActivityCoefficientResult objects. """ results: list[ActivityCoefficientResult] @property def by_types(self) -> dict[str, dict[str, ActivityCoefficientResult]]: """ Group the ActivityCoefficientResult by their type, e.g., if they are a `derivative` or `integrated` property. Returns ------- dict Nested dictionary of ActivityCoefficientResult sorted by property, then by molecule name. """ data: dict[str, dict[str, ActivityCoefficientResult]] = {} for m in self.results: data.setdefault(m.property_type, {})[m.mol] = m return data
[docs] def get(self, mol: str, property_type: Literal["derivative", "integrated"]) -> ActivityCoefficientResult: """ Get an ActivityCoefficientResult object for a given `property_type` and `mol`. Parameters ---------- mol: str Molecule name. property_type: str Type of activity coefficient property. """ key = "derivative" if property_type.lower().startswith("d") else "integrated" try: return self.by_types[key][mol] except KeyError as e: raise KeyError(f"property type {property_type} and mol {mol} not in {self.by_types}") from e
def __iter__(self): """Creates an iterable type object.""" return iter(self.results) def __len__(self) -> int: """Allows len(ActivityMetadata) to return num systems in registry.""" return len(self.results)