Source code for httk.atomistic.sites_class_view
"""
A view presenting any sites backend as a Sites object (the class representation).
"""
import fractions
from functools import cached_property
from typing import Any, Self
from httk.core import FracVector, unwrap
from ._vector_guards import to_fracvector, to_precision
from .sites import Sites
from .sites_backend import SitesBackend
from .sites_like import SitesLike
from .sites_view import SitesView
[docs]
class SitesClassView(SitesView, Sites):
"""
A view presenting an underlying sites backend as a ``Sites`` object.
This view is a genuine ``Sites``, so it can be passed anywhere a Sites is accepted.
Its state is built lazily on first access from the backend.
"""
_backend: SitesBackend
def __new__(cls, obj: SitesLike, **hints: Any) -> Self:
if isinstance(obj, cls):
return obj
backend = cls._prepare_backend(obj, hints)
instance = super().__new__(cls)
instance._backend = backend
return instance
def __init__(self, obj: SitesLike, **hints: Any) -> None:
pass
# Validate then assign: failed fills leave no partial presentation state, and fills must not
# read shadowed attributes or they recurse.
def _fill_reduced_coords(self) -> None:
coords = to_fracvector(self._backend.reduced_coords)
if coords.dim != () and not (len(coords.dim) == 2 and coords.dim[1] == 3):
raise ValueError("Sites reduced_coords must be an Nx3 vector-like")
self.__dict__["_reduced_coords"] = coords
def _fill_precision(self) -> None:
self.__dict__["_precision"] = to_precision(self._backend.precision)
@cached_property
def _reduced_coords(self) -> FracVector: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride]
self._fill_reduced_coords()
return self.__dict__["_reduced_coords"]
@cached_property
def _precision(self) -> fractions.Fraction | None: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride]
self._fill_precision()
return self.__dict__["_precision"]
[docs]
def unwrap(self) -> Any:
return unwrap(self._backend)