Source code for httk.atomistic.models.species.plain_view
"""
A view presenting any species backend as an OPTIMADE species dict.
"""
from typing import Any, Self
from httk.core import unwrap
from httk.atomistic.models.species.backend import SpeciesBackend
from httk.atomistic.models.species.like import SpeciesLike
from httk.atomistic.models.species.view_base import SpeciesViewBase
[docs]
class PlainSpeciesView(SpeciesViewBase, dict):
r"""
A view presenting an underlying species backend as an OPTIMADE species dict.
This view is a genuine ``dict`` carrying the OPTIMADE ``species`` fields (optional
fields that are ``None`` are omitted; list-valued fields are plain lists). Unlike the
immutable-subclass views, a dict is mutable, so this view is a detached copy: mutating
it does not affect the underlying backend.
:param obj: The species-like object to present.
:param \**hints: Backend-selection hints.
"""
_backend: SpeciesBackend
def __new__(cls, obj: SpeciesLike, **hints: Any) -> Self:
if isinstance(obj, cls):
return obj
backend = cls._prepare_backend(obj, hints)
payload: dict[str, Any] = {
"name": backend.name,
"chemical_symbols": list(backend.chemical_symbols),
"concentration": [float(value) for value in backend.concentration],
}
if backend.mass is not None:
payload["mass"] = list(backend.mass)
if backend.original_name is not None:
payload["original_name"] = backend.original_name
if backend.attached is not None:
payload["attached"] = list(backend.attached)
if backend.nattached is not None:
payload["nattached"] = list(backend.nattached)
# _httk_charges/_httk_spins are JSON-number floats; exact values live on Species.
charges = backend.charges
if charges is not None and any(value is not None for value in charges):
payload["_httk_charges"] = [None if value is None else float(value) for value in charges]
spins = backend.spins
if spins is not None and any(value is not None for value in spins):
payload["_httk_spins"] = [None if value is None else float(value) for value in spins]
labels = backend.labels
if labels is not None and any(value is not None for value in labels):
payload["_httk_labels"] = list(labels)
raw = backend.unwrap()
if isinstance(raw, dict) and "_httk_concentration_precision" in raw:
payload["_httk_concentration_precision"] = [
None if value is None else float(value) for value in backend.concentration_precision or ()
]
instance = super().__new__(cls)
# dict is mutable, so its contents are initialized here in __new__ (keeping __init__ a no-op),
# so that rewrapping an existing view via cls(view) does not re-initialize it.
dict.__init__(instance)
instance.update(payload)
instance._backend = backend
return instance
def __init__(self, obj: SpeciesLike, **hints: Any) -> None:
pass
[docs]
def unwrap(self) -> Any:
"""Return the raw object behind the backend.
:return: The unwrapped source object.
"""
return unwrap(self._backend)
[docs]
def unview(self) -> dict[str, Any]:
"""Return the presented species as a plain mapping.
:return: The detached presentation mapping.
"""
# The view IS its presentation dict (already a detached copy); shed to a plain dict.
return dict(self)