Source code for httk.atomistic.unitcell_structure_view

"""
A view presenting any structure backend as a Structure (the Unitcell representation).
"""

from functools import cached_property
from typing import Any, Self

from httk.core import unwrap

from .cell import Cell
from .sites import Sites
from .species import Species
from .structure import (
    Structure,
    _check_sites_length,
    _check_species_at_sites,
    _check_species_names,
    _norm_cell,
    _norm_sites,
    _norm_species,
    _norm_species_at_sites,
)
from .structure_backend import StructureBackend
from .structure_like import StructureLike
from .structure_view import StructureView


[docs] class UnitcellStructureView(StructureView, Structure): """ A view presenting an underlying structure backend as a ``Structure``. This view is a genuine ``Structure``, so it can be passed anywhere a Structure is accepted. Each component is normalized lazily on first access. For an ASU-backed view, accessing ``cell`` or ``species`` never triggers expansion. """ _backend: StructureBackend def __new__(cls, obj: StructureLike, **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: StructureLike, **hints: Any) -> None: pass def _fill_cell(self) -> None: self.__dict__["_cell"] = _norm_cell(self._backend.cell) def _fill_species(self) -> None: species = _norm_species(self._backend.species) _check_species_names(species) self.__dict__["_species"] = species def _fill_species_at_sites(self) -> None: # Exception to the no-shadowed-read rule: this cheap dependency is acyclic because # species never reads species_at_sites. species_at_sites = _norm_species_at_sites(self._backend.species_at_sites) _check_species_at_sites(species_at_sites, self._species) self.__dict__["_species_at_sites"] = species_at_sites def _fill_sites(self) -> None: sites = _norm_sites(self._backend.sites) _check_sites_length(sites, self._species_at_sites) self.__dict__["_sites"] = sites @cached_property def _cell(self) -> Cell: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride] self._fill_cell() return self.__dict__["_cell"] @cached_property def _sites(self) -> Sites: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride] self._fill_sites() return self.__dict__["_sites"] @cached_property def _species(self) -> tuple[Species, ...]: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride] self._fill_species() return self.__dict__["_species"] @cached_property def _species_at_sites(self) -> tuple[str, ...]: # type: ignore[override] # pyright: ignore[reportIncompatibleVariableOverride] self._fill_species_at_sites() return self.__dict__["_species_at_sites"]
[docs] def unwrap(self) -> Any: return unwrap(self._backend)