Metadata-Version: 2.5
Name: matdomain-structure
Version: 0.1.0
Summary: Neutral immutable structure values for materials science
Author: CMPDC
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: pydantic<3,>=2.13
Requires-Dist: pymatgen-core>=2026.8.13
Description-Content-Type: text/markdown

# matdomain-structure

Immutable, source-neutral values for one exact crystallographic structure
occurrence. The package preserves the input cell and caller-provided site sequence,
provides deterministic canonical bytes and digests, and exposes one explicit
site-wrapping transformation.

Python 3.12 or newer is required. Install the published distribution with:

```bash
pip install matdomain-structure
```

From this workspace, install it directly with:

```bash
python -m pip install -e ./packages/matdomain-structure
```

```python
from matdomain.structure import Lattice, Site, Species, StructureValue

structure = StructureValue(
    lattice=Lattice(matrix=((3.0, 0.0, 0.0), (0.0, 3.0, 0.0), (0.0, 0.0, 3.0))),
    periodic_axes=(True, True, True),
    sites=(
        Site(fractional_coordinates=(0.0, 0.0, 0.0), species=(Species(kind="element", symbol="Li", occupancy=1.0),)),
    ),
)

digest = structure.canonical_digest()
wrapped = structure.wrap_sites_to_unit_cell()
```

Lattice rows are measured in angstroms, and each periodic-axis flag applies to
the corresponding lattice row. Charge is measured in elementary-charge units
and is `None` when unknown. Fractional coordinates are retained exactly until
`wrap_sites_to_unit_cell()` is called; that operation wraps only periodic axes
and reports every site whose coordinate representative changed.

Each site has at least one non-vacancy component and occupancy totaling one
within an absolute tolerance of `1e-8`. Partial occupancy uses one explicit
vacancy component. Site order remains input order; species within a site are
canonicalized by identity, including optional isotope mass number, oxidation
state, and spin. The versioned canonical bytes are the exact Python wire profile
returned by `canonical_bytes()` and contain no product provenance or scene data.
Spin is the optional idealized species value represented by pymatgen, not a
calculated site magnetic moment.

This distribution versions independently and uses tags of the form
`matdomain-structure-vX.Y.Z`. The workspace release workflow checks and
builds both distributions but publishes only the package named by the tag.
