Source code for httk.atomistic.models.bareprototype.recognized

"""The structure-to-prototype recognition adapter."""

from functools import cached_property
from typing import Any, Self

from httk.core import unwrap

from httk.atomistic.models.bareprototype.backend import BarePrototypeBackend
from httk.atomistic.models.bareprototype.bareprototype import BarePrototype
from httk.atomistic.models.formula.backend import ChemicalFormulaBackend
from httk.atomistic.models.formula.view_base import ChemicalFormulaViewBase
from httk.atomistic.models.structure.backend import StructureBackend
from httk.atomistic.models.structure.view import StructureView
from httk.atomistic.models.structuretype.backend import StructuretypeBackend
from httk.atomistic.models.structuretype.view_base import StructuretypeViewBase


[docs] class RecognizedBarePrototype(BarePrototypeBackend): r"""Recognize an ordinary structure or template lazily as a prototype. Recognition resolves an exact fundamental-domain template, then retains only its standard-setting Wyckoff occupations and anonymous class partition. The original source remains available through ``unwrap()``. :param obj: The structure-like source to recognize. :param \*\*hints: Backend-selection and recognition hints. """ kind = "structure" _source: Any _tolerance: float | None _limit_denominator: int | None @classmethod def _backend_adopt(cls, obj: Any, **hints: Any) -> Self | None: r"""Adopt a template-like or structure-like class anchor. :param obj: The source object to adopt. :param \**hints: Backend-selection hints. :return: An initialized backend, or ``None`` when this backend declines ``obj``. """ if hints and hints.get("kind", "structure") != "structure": return None from httk.atomistic.models.protostructure.backend import ProtostructureBackend from httk.atomistic.models.protostructure.view_base import ProtostructureViewBase # Assigned classifications use the dedicated erasure adapter. # Chemical formulas are not structure sources. if isinstance(obj, (ProtostructureBackend, ProtostructureViewBase)): return None if isinstance(obj, (ChemicalFormulaBackend, ChemicalFormulaViewBase)): return None if isinstance(obj, (StructuretypeBackend, StructuretypeViewBase, StructureView, StructureBackend)): return cls(obj, **hints) source_hints = { name: value for name, value in hints.items() if name not in ("kind", "tolerance", "limit_denominator") } try: StructureBackend._select_backend(obj, **source_hints) except TypeError as exc: if str(exc) == f"Cannot represent {type(obj)} as StructureBackend": return None raise return cls(obj, **hints) def __init__(self, obj: Any, **hints: Any) -> None: self._source = obj self._tolerance = hints.get("tolerance") self._limit_denominator = hints.get("limit_denominator") @cached_property def _derived(self) -> BarePrototype: from httk.atomistic.models.structuretype.fundamental_view import FundamentalDomainTemplateView source = self._source template = FundamentalDomainTemplateView( source, tolerance=self._tolerance, limit_denominator=self._limit_denominator ).unview() return BarePrototype(template.spacegroup, [(site.wyckoff, site.species) for site in template.wyckoff_sites])
[docs] def resolve(self) -> BarePrototype: """Return the complete recognized prototype.""" return self._derived
@property def spacegroup(self): return self._derived.spacegroup @property def occupations(self): return self._derived.occupations
[docs] def unwrap(self) -> Any: """Return the original recognition source.""" return unwrap(self._source)