httk.atomistic.models.cell ========================== .. py:module:: httk.atomistic.models.cell Submodules ---------- .. toctree:: :maxdepth: 1 /reference/autoapi/httk/atomistic/models/cell/api/index /reference/autoapi/httk/atomistic/models/cell/backend/index /reference/autoapi/httk/atomistic/models/cell/cell/index /reference/autoapi/httk/atomistic/models/cell/like/index /reference/autoapi/httk/atomistic/models/cell/numeric/index /reference/autoapi/httk/atomistic/models/cell/numeric_view/index /reference/autoapi/httk/atomistic/models/cell/params/index /reference/autoapi/httk/atomistic/models/cell/params_view/index /reference/autoapi/httk/atomistic/models/cell/plain/index /reference/autoapi/httk/atomistic/models/cell/plain_view/index /reference/autoapi/httk/atomistic/models/cell/record/index /reference/autoapi/httk/atomistic/models/cell/view/index /reference/autoapi/httk/atomistic/models/cell/view_base/index Attributes ---------- .. autoapisummary:: httk.atomistic.models.cell.CellLike Classes ------- .. autoapisummary:: httk.atomistic.models.cell.CellAPI httk.atomistic.models.cell.CellBackend httk.atomistic.models.cell.Cell httk.atomistic.models.cell.NumericCell httk.atomistic.models.cell.CellNumericView httk.atomistic.models.cell.CellParams httk.atomistic.models.cell.CellParamsView httk.atomistic.models.cell.PlainCell httk.atomistic.models.cell.PlainCellView httk.atomistic.models.cell.CellView httk.atomistic.models.cell.CellViewBase Package Contents ---------------- .. py:class:: CellAPI Bases: :py:obj:`abc.ABC` Abstract base class for the canonical cell interface. It declares the exact accessors that every cell backend produces from its own native representation and every cell view builds its presentation from: the ``basis`` of 3x3 lattice vectors (``scale * unscaled_basis``), the positive ``scale``, and the ``unscaled_basis``. All three are exact httk-core vectors; this is the single interchange format, with no pairwise conversion between backends. .. py:property:: basis :type: httk.core.SurdVector :abstractmethod: Return the scaled lattice vectors. .. py:property:: scale :type: httk.core.SurdScalar :abstractmethod: Return the positive factor applied to ``unscaled_basis``. .. py:property:: unscaled_basis :type: httk.core.SurdVector :abstractmethod: Return the lattice vectors before applying ``scale``. .. py:property:: precision :type: fractions.Fraction | None How precisely the basis was stated, as an absolute length, or ``None`` if unknown. A backend that knows its source's precision overrides this; one that does not — a bare matrix of numbers with no provenance — inherits ``None``. :return: The absolute basis precision, or ``None`` when it is unknown. .. py:property:: periodicity :type: tuple[bool, bool, bool] Which of the three basis rows is a genuine lattice translation. A backend that knows its periodicity overrides this; one that does not inherit ``(True, True, True)``. A cell described only by six lattice parameters or a bare matrix is interpreted as a fully periodic crystal. :return: Flags identifying the periodic basis rows. .. py:method:: metric() Return the exact Gram matrix of the scaled basis. :return: The Gram matrix of the cell vectors. .. py:property:: lengths :type: tuple[httk.core.SurdScalar, Ellipsis] Return exact lengths where representable, with a deterministic rational fallback otherwise. :return: The three cell-vector lengths. .. py:property:: angles :type: tuple[fractions.Fraction, Ellipsis] Return ``(alpha, beta, gamma)`` exactly where representable, with a deterministic rational fallback otherwise. :return: The crystallographic angles in degrees. .. py:property:: volume :type: httk.core.SurdScalar Return the exact absolute determinant of the basis. :return: The cell volume. :raises ValueError: If the cell is not periodic in all three directions. .. py:class:: CellBackend(backend, **hints) Bases: :py:obj:`httk.core.Backend`\ [\ :py:obj:`CellBackend`\ ], :py:obj:`httk.atomistic.models.cell.api.CellAPI` Abstract base class for all backends of cell data. Concrete backends carry a native representation and produce the canonical 3x3 ``basis`` declared by ``CellAPI`` from it. .. py:attribute:: backend_classes :type: ClassVar[list[type[httk.core.Backend[Any]]]] .. py:class:: Cell(basis, scale = 1, precision = None, periodicity = None) Bases: :py:obj:`httk.atomistic.models.cell.backend.CellBackend` A crystallographic cell: its basis, the 3x3 matrix of cell vectors, held **exactly**. The lattice vectors are the rows of ``basis``. Internally a Cell factors that basis into a positive :class:`~httk.core.SurdScalar` ``scale`` times an ``unscaled_basis`` (a :class:`~httk.core.SurdVector` of shape ``(3, 3)``), with ``basis == scale * unscaled_basis``. The split lets an overall length factor be carried symbolically: a hexagonal cell of lattice parameter ``a`` and ratio ``c/a`` is the exact ``unscaled`` rows ``(1, 0, 0)``, ``(-1/2, sqrt(3)/2, 0)``, ``(0, 0, c/a)`` scaled by ``a`` — so the ``sqrt(3)`` stays exact regardless of ``a``. A cell built from an absolute basis simply has ``scale == 1``. Numbers embed exactly: rationals (and rational-valued floats) stay rational, and a :class:`~httk.core.SurdVector` basis keeps its radicals. Derived quantities retain exact forms where the underlying operation stays in the supported exact fields, including the usual metric-rational crystallographic case: ``lengths`` use :meth:`~httk.core.SurdVector.sqrt_of` for rational squared row lengths when the rational radicand is a perfect square or stays below the deterministic small-radicand threshold, ``angles`` (degrees) use the exact reverse-Niven :meth:`~httk.core.SurdScalar.acos_degrees` where possible, ``volume`` comes from the exact determinant, and ``metric`` is the exact Gram matrix, which may itself contain surds. For larger rational or irrational squared lengths, ``lengths``/``angles`` fall back to a deterministic rational approximation (documented per accessor). Exact accessors return vector objects — render them with ``.to_floats()`` (nested plain-float lists, numpy-free), ``float(...)`` on scalars, :meth:`numeric` (true numpy arrays), or a view of your choice. A cell also records its :attr:`periodicity`, which defaults to periodic in all three directions. Where it is not, the basis stops being purely a lattice and becomes partly a *coordinate frame*: see :attr:`periodicity` for what that means and :attr:`periodic_measure` for the quantity that replaces :attr:`volume`. :param basis: The three cell vectors, one per row. :param scale: The positive factor separated from ``basis``. :param precision: The absolute precision carried from the source, if known. :param periodicity: Flags identifying which basis rows are lattice translations. .. py:property:: scale :type: httk.core.SurdScalar The overall (strictly positive) length factor. :return: The factor applied to ``unscaled_basis``. .. py:property:: unscaled_basis :type: httk.core.SurdVector The 3x3 cell vectors before applying ``scale``. :return: The unscaled lattice vectors. .. py:property:: basis :type: httk.core.SurdVector The 3x3 lattice vectors ``scale * unscaled_basis``. :return: The scaled lattice vectors. .. py:property:: precision :type: fractions.Fraction | None How precisely this basis was stated, as an absolute length, or ``None`` if unknown. In the same units as the basis itself, so for ordinary crystallographic data it is an ångström. Derived from the source's written digits and any stated uncertainty — a CIF cell edge of ``5.6402(3)`` is precise to ``3e-4``, not to the ``1e-4`` its four decimals alone would suggest. ``None`` means unknown, which is not the same as exact. It is what a cell built by hand or from a bare matrix reports. :return: The absolute precision, or ``None`` when it is unknown. .. py:property:: periodicity :type: tuple[bool, bool, bool] Which of the three basis rows is a genuine lattice translation. ``(True, True, True)`` — the default, and what every ordinary crystal is. A slab is ``(True, True, False)``, a nanowire has one ``True``, and an isolated molecule is ``(False, False, False)``. A row flagged ``False`` is **not** a lattice vector. It is only a frame: it says what a fractional coordinate means along that direction, and nothing more. Coordinates there are unbounded — freely below 0 or above 1 — and are never wrapped into ``[0, 1)``. There is no vacuum and no padding involved, so making that row a unit vector simply means the coordinate along it *is* a length in the basis's units. This is the same notion, in the same order, as OPTIMADE's ``dimension_types``. :return: Flags identifying the periodic basis rows. .. py:property:: nperiodic_dimensions :type: int How many of the three directions are periodic. :return: The number of periodic directions. .. py:method:: numeric() Return a plain-numpy presentation of this cell. :return: The numpy-backed presentation. :raises ImportError: If numpy is unavailable. .. py:method:: metric() Return the exact, potentially surd-valued Gram matrix ``matrix * matrix^T``. :return: The Gram matrix of the cell vectors. .. py:property:: lengths :type: tuple[httk.core.SurdScalar, Ellipsis] The lengths of the three cell vectors (the scaled row norms). Exact via :meth:`~httk.core.SurdVector.sqrt_of` when the row's squared length is a perfect-square rational or a rational with numerator times denominator at most ``10**18``. Larger rational radicands and irrational squared lengths use a deterministic rational approximation at ``_FALLBACK_PREC``. :return: The three cell-vector lengths. .. py:property:: angles :type: tuple[fractions.Fraction, Ellipsis] The cell angles ``(alpha, beta, gamma)`` in degrees, as exact ``Fraction`` values. Following the crystallographic convention, ``alpha`` is the angle between rows ``b`` and ``c``, ``beta`` between ``a`` and ``c``, and ``gamma`` between ``a`` and ``b``. Angles are scale-independent, so they are computed from the unscaled basis. The cosine is formed exactly in the surd field and reversed through the Niven table (:meth:`~httk.core.SurdScalar.acos_degrees`) for an exact answer; a non-Niven angle falls back to a deterministic :func:`~httk.core.exactmath.acos` at ``_FALLBACK_PREC``. :return: ``(alpha, beta, gamma)`` in degrees. .. py:property:: volume :type: httk.core.SurdScalar The cell volume, the exact absolute determinant of ``basis``. Defined only for a fully periodic cell, and raises :class:`ValueError` otherwise. For anything less, the determinant mixes real lattice vectors with frame vectors, so it is not a volume: it changes when a frame vector is rescaled, even though nothing about the material did. Any density or packing fraction derived from it would inherit that. See :attr:`periodic_measure` for the quantity that *is* defined. :return: The absolute determinant of the basis. :raises ValueError: If the cell is not periodic in all three directions. .. py:property:: periodic_measure :type: httk.core.SurdScalar The size of the repeating unit, whatever its dimension. A volume for a crystal, an area for a slab, a length for a nanowire. For a fully non-periodic cell there is no repeating unit and this is the empty product, ``1``, which is dimensionless rather than a length of any kind. Exact in the crystallographic case. The 3D case is the determinant and needs no square root at all; the 2D and 1D cases take the same square root that :attr:`lengths` does, so they are exact whenever the squared measure is a rational with a small radicand and fall back to a deterministic rational approximation otherwise. :return: The measure of the periodic sublattice. .. py:type:: CellLike :canonical: httk.atomistic.models.cell.backend.CellBackend | httk.atomistic.models.cell.view_base.CellViewBase | httk.atomistic.models.cell.cell.Cell | httk.core.VectorLike .. py:class:: NumericCell(cell) A plain-numpy presentation of a :class:`~httk.atomistic.Cell`. Where a ``Cell`` holds its geometry **exactly** (a :class:`~httk.core.SurdVector` basis, exact ``SurdScalar`` lengths/volume, exact ``Fraction`` angles), a ``NumericCell`` mirrors that interface but returns plain numpy numbers — a ``float64`` :class:`numpy.ndarray` for every vector and a plain :class:`float` for every scalar — for callers who do not need exact arithmetic and just want numpy arrays. The presentation is numpy-backed, so constructing a ``NumericCell`` **requires numpy** (the ``httk-atomistic[numpy]`` extra) and raises :class:`ImportError` eagerly when it is unavailable. The exact object is always one hop away via :attr:`exact`. :param cell: The cell or cell-like object to present. .. py:property:: scale :type: float The overall length factor. :return: The scale as a floating-point value. .. py:property:: precision :type: float | None The cell precision, or ``None`` if unknown. :return: The absolute precision as a floating-point value. .. py:property:: periodicity :type: tuple[bool, bool, bool] Which of the three basis rows is a genuine lattice translation. :return: Flags identifying the periodic basis rows. .. py:property:: nperiodic_dimensions :type: int How many of the three directions are periodic. :return: The number of periodic directions. .. py:property:: unscaled_basis :type: httk.core.NumericVector The 3x3 cell vectors before applying ``scale``. :return: The unscaled lattice vectors as floating-point values. .. py:property:: basis :type: httk.core.NumericVector The 3x3 lattice vectors ``scale * unscaled_basis``. :return: The scaled lattice vectors as floating-point values. .. py:property:: lengths :type: httk.core.NumericVector The three cell-vector lengths. :return: The lengths as floating-point values. .. py:property:: angles :type: httk.core.NumericVector The cell angles ``(alpha, beta, gamma)`` in degrees. :return: The angles as floating-point values. .. py:property:: volume :type: float The cell volume. :return: The volume as a floating-point value. :raises ValueError: If the exact cell is not periodic in all three directions. .. py:method:: metric() The Gram matrix ``basis * basis^T``. :return: The Gram matrix as floating-point values. .. py:property:: exact :type: httk.atomistic.models.cell.cell.Cell The exact cell this presentation wraps. :return: The exact cell. .. py:class:: CellNumericView(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.view_base.CellViewBase`, :py:obj:`httk.atomistic.models.cell.numeric.NumericCell` A view presenting an underlying cell backend as a ``NumericCell``. This view is a genuine ``NumericCell``, so it can be passed anywhere one is accepted. Its exact ``Cell`` is built lazily from the backend on first access, preserving the scale/unscaled split. Like a ``NumericCell`` it requires numpy (raising :class:`ImportError` otherwise). :param obj: The cell-like object to present. :param \**hints: Backend-selection hints. .. py:method:: unwrap() Return the raw object behind the backend. :return: The unwrapped source object. .. py:method:: unview() Return this presentation as a standalone numeric cell. :return: The plain-numpy presentation. .. py:class:: CellParams(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.backend.CellBackend` Backend for a cell backed by cell parameters ``(a, b, c, alpha, beta, gamma)``. The native representation is a flat length-6 vector-like of the cell-vector lengths ``a``/``b``/``c`` and the angles ``alpha``/``beta``/``gamma`` in degrees, stored as exact :class:`~fractions.Fraction` values (parsed via :func:`~httk.core.exactmath.any_to_fraction`). The exact ``basis`` is derived lazily and cached using the standard crystallographic orientation convention (first cell vector along x, second in the xy-plane); for the common Niven angles it is exact (radicals intact). Since parameters carry no separate length factor, ``scale`` is the exact ``1`` and ``unscaled_basis == basis``. Parameters carry neither orientation nor periodicity, so a cell → parameters → cell round-trip reproduces lengths and angles, and reproduces volume only for a fully periodic source. Reconstruction uses the fully periodic default and therefore discards any non-3D periodicity as well as the original orientation. ``unwrap`` returns the original raw object. :param obj: The six cell parameters in crystallographic order. :param \**hints: Backend-selection hints. .. py:property:: basis :type: httk.core.SurdVector Return the basis derived from the stored parameters. :return: The standard-orientation cell vectors. .. py:property:: scale :type: httk.core.SurdScalar Return the unit scale factor. :return: The factor applied to ``unscaled_basis``. .. py:property:: unscaled_basis :type: httk.core.SurdVector Return the parameter-derived basis before scaling. :return: The cell vectors. .. py:property:: lengths :type: tuple[httk.core.SurdScalar, Ellipsis] Return the natively stored cell-vector lengths. :return: The exact stored ``a``, ``b``, and ``c`` lengths. .. py:property:: angles :type: tuple[fractions.Fraction, Ellipsis] Return the natively stored cell angles in degrees. :return: The exact stored ``alpha``, ``beta``, and ``gamma`` angles. .. py:property:: params :type: tuple[fractions.Fraction, Ellipsis] The stored ``(a, b, c, alpha, beta, gamma)`` in degrees. :return: The exact cell parameters. .. py:method:: unwrap() Return the original parameter object. :return: The raw parameter representation. .. py:class:: CellParamsView(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.view_base.CellViewBase`, :py:obj:`tuple` A view presenting an underlying cell backend as cell parameters. This view is a genuine flat 6-tuple ``(a, b, c, alpha, beta, gamma)`` with the angles in degrees, built eagerly and immutable, with the elements also available as the named properties ``a``/``b``/``c``/``alpha``/``beta``/``gamma``. Parameters carry no orientation, so converting a cell to parameters is lossy: reconstructing a cell from this view reproduces the lengths and angles, and reproduces volume only for a fully periodic source. The reconstruction inherits the fully periodic default, so this view discards the source periodicity as well as the original cell-vector orientation. :param obj: The cell-like object to present. :param \**hints: Backend-selection hints. .. py:property:: a :type: float The length of the first cell vector. :return: The first vector length. .. py:property:: b :type: float The length of the second cell vector. :return: The second vector length. .. py:property:: c :type: float The length of the third cell vector. :return: The third vector length. .. py:property:: alpha :type: float The angle between the second and third cell vectors, in degrees. :return: The alpha angle. .. py:property:: beta :type: float The angle between the first and third cell vectors, in degrees. :return: The beta angle. .. py:property:: gamma :type: float The angle between the first and second cell vectors, in degrees. :return: The gamma angle. .. py:method:: unwrap() Return the raw object behind the backend. :return: The unwrapped source object. .. py:method:: unview() Return the presented parameters as a plain tuple. :return: The six cell parameters. .. py:class:: PlainCell(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.backend.CellBackend` Backend for a cell backed by a raw 3x3 list or tuple of numbers (or any 3x3 vector-like). The native representation is preserved verbatim (one cell vector per row); the exact :class:`~httk.core.SurdVector` ``basis`` is built lazily and cached. This representation carries no separate length factor, so ``scale`` is the exact ``1`` and ``unscaled_basis == basis``. ``unwrap`` returns the original raw object. :param obj: The raw 3x3 basis representation. :param \**hints: Backend-selection hints. .. py:property:: basis :type: httk.core.SurdVector Return the raw basis in the canonical representation. :return: The cell vectors. .. py:property:: scale :type: httk.core.SurdScalar Return the unit scale factor. :return: The factor applied to ``unscaled_basis``. .. py:property:: unscaled_basis :type: httk.core.SurdVector Return the basis before scaling. :return: The cell vectors. .. py:method:: unwrap() Return the original basis object. :return: The raw basis representation. .. py:class:: PlainCellView(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.view_base.CellViewBase`, :py:obj:`tuple` A view presenting an underlying cell backend as the raw 3x3 basis matrix of floats. This view is a genuine tuple of three cell-vector rows (the scaled lattice vectors rendered to floats from the exact ``basis``), built eagerly and immutable. :param obj: The cell-like object to present. :param \**hints: Backend-selection hints. .. py:method:: unwrap() Return the raw object behind the backend. :return: The unwrapped source object. .. py:method:: unview() Return the presented basis as a plain tuple. :return: The three cell-vector rows. .. py:class:: CellView(obj, **hints) Bases: :py:obj:`httk.atomistic.models.cell.view_base.CellViewBase`, :py:obj:`httk.atomistic.models.cell.cell.Cell` A view presenting an underlying cell backend as a ``Cell``. This view is a genuine ``Cell``, so it can be passed anywhere a Cell is accepted. Its state is built lazily on first access from the backend. :param obj: The cell-like object to present. :param \**hints: Backend-selection hints. .. py:method:: unwrap() Return the raw object behind the backend. :return: The unwrapped source object. .. py:method:: unview() Return this presentation as a standalone cell. :return: The exact cell representation. .. py:class:: CellViewBase Bases: :py:obj:`httk.core.View`\ [\ :py:obj:`httk.atomistic.models.cell.backend.CellBackend`\ ] Abstract base class for all views of cell data.