httk.atomistic.symmetry.canonical¶
Canonical forms for noisy input: tolerant recognition composed with exact normalization.
canonical_asu() bridges the two layers. Before tolerant recognition, the exact unit-cell geometry
is put in an anonymous P1 frame, giving spglib one deterministic basis, origin, and site order for
every exact re-expression of the same measured structure. The tolerant layer
(recognize_asu(), backed by spglib) then snaps that stable input onto a space
group within a Cartesian tolerance. The exact layer selects an anonymous protostructure-first
representative. canonical_asu_legacy() retains the metric-first convention.
This module is deliberately outside lift.py: lift imports recognition (for its tolerance
helpers) and stays spglib-free, while this composer imports both.
Attributes¶
Functions¶
|
Return the legacy metric-first canonical ASU of a measured structure's symmetry. |
|
Canonicalize a structure or classification without general upward symmetry search. |
Module Contents¶
- httk.atomistic.symmetry.canonical.canonical_asu_legacy(structure, *, tolerance=None, factors=(Fraction(1, 5), 1, 5), lift=False, preserve_chirality=True)¶
Return the legacy metric-first canonical ASU of a measured structure’s symmetry.
This is the noisy-input counterpart to
canonicalize_legacy(): it first normalizes the exact measured geometry in P1, recognizes its symmetry with spglib, and then canonicalizes the recognized result exactly. P1 preconditioning prevents spglib’s tolerance-boundary result from depending on an equivalent input shear, origin shift, or site ordering.An
ASUStructureinput is expanded to its unit cell first and the symmetry is re-recognized from the actual coordinates – always from the geometry, never the declared label. Re-recognition can raise a declared symmetry (a hand-written low-symmetry cell whose coordinates in fact support more) and can also lower it (a declared symmetry the coordinates do not support at the derived tolerance).Recognition is swept over the
base * factorsymprecs from loosest to tightest. A member is accepted only when its recognized model reproduces every input site within the base tolerance (never the swept one), by an injective same-species match, and matches the per-species site counts. The first accepted member wins – by the same operation-count monotonicity the loosest fitting member is the highest-symmetry one – so recognition (and the expensive stage) runs once in the common case, and a looser member still rescues a tolerance-boundary flip a tighter one fails.liftselects the expensive stage applied to that winner:lift=False(default): it is mapped to the deterministic canonical representative within its recognized group – the exact terminal representation (setting, origin, orbit representatives, basis orientation all fixed), returned without searching upward. The result is the canonical form of the recognized symmetry; no pseudosymmetry above it is sought.lift=True: it is additionally run through the exact upward search (canonicalize_legacy()) to find higher pseudosymmetry the recognition missed. This is exact but can be expensive – minutes and beyond for low-symmetry, many-atom cells.
Tolerance bound: the recognition stage is held to the base tolerance – every returned atom sits within
baseof the input. Underlift=Falsethat is the whole bound (no further hops). Underlift=Trueeach lift hop can move coordinates and snap the metric by up to anotherbaseand the residual/path are not re-checked here, so the returned structure’s distance from the input is bounded roughly bybase * (1 + hops).Determinism: the recognition stage is floating-point/spglib-based, so its outcome is reproducible on one platform but may differ across floating-point architectures or spglib builds. The exact stage is platform-independent and erases spglib’s representational freedom for ordinary rational crystallographic Gram matrices, so cross-platform variation is confined to which symmetry is accepted near a tolerance boundary, never to how an accepted symmetry is represented. An exact non-rational Gram whose canonical Cartesian factor requires nested radicals outside the supported surd field remains idempotent but can retain its input’s global Cartesian rotation. Free-parameter values come from row-Hermite chart projection of the measured coordinates, so two noisy measurements of the same crystal can reach the same Wyckoff choices with slightly different rational parameter values.
- Parameters:
structure (httk.atomistic.models.structure.like.StructureLike) – The measured structure,
UnitcellStructureorASUStructure.tolerance (float | None) – The base Cartesian tolerance, or
Noneto derive it from the structure’s stated precision (structure_tolerance()).factors (tuple[fractions.Fraction | float | int, ...]) – Multipliers for the recognition symprec sweep; each candidate symprec is
base * factor.lift (bool) – Whether to search upward for pseudosymmetry above the recognized group (default
False: return the canonical representative of the recognized symmetry).preserve_chirality (bool) – How enantiomorphic space groups are canonicalized. By default (
True) the recognized group is kept, so a genuinely chiral crystal retains its handedness. WhenFalsea result landing in the higher member of one of the 11 enantiomorphic pairs (76/78, 91/95, 92/96, 144/145, 151/153, 152/154, 169/170, 171/172, 178/179, 180/181, 212/213) is mapped to the LOWER-numbered member by an exact chirality-flipping transformation (fractional coordinatesf -> (-f) mod 1with the cell basis unchanged – the Cartesian inversionr -> -r– and the group swapped to its partner), so an enantiomorphic pair shares one canonical representative and the canonical labels of the two partners coincide. The exact bridgenormalize_chirality()maps a preserved (True) result to the normalized (False) one directly, without re-canonicalizing. A structure carrying site moments is never flipped (axial vectors are out of scope under improper maps) and is left in its own group regardless of this flag.
- Returns:
The canonical asymmetric unit.
- Raises:
ImportError – If spglib is unavailable when symmetry must be searched (the error names the
httk-atomistic[default]extra).ValueError – If recognition fails or is rejected at every swept tolerance.
- Return type:
- httk.atomistic.symmetry.canonical.canonicalize(structure: httk.atomistic.models.bareprototype.backend.BarePrototypeBackend, *, symmetry: Literal['detect', 'declared'] = 'detect', tolerance: float | None = None, factors: tuple[fractions.Fraction | float | int, ...] = (Fraction(1, 5), 1, 5), preserve_chirality: bool = True, timeout: float | None = 120.0) httk.atomistic.models.bareprototype.bareprototype.BarePrototype¶
- httk.atomistic.symmetry.canonical.canonicalize(structure: httk.atomistic.models.bareprotostructure.backend.BareProtostructureBackend, *, symmetry: Literal['detect', 'declared'] = 'detect', tolerance: float | None = None, factors: tuple[fractions.Fraction | float | int, ...] = (Fraction(1, 5), 1, 5), preserve_chirality: bool = True, timeout: float | None = 120.0) httk.atomistic.models.bareprotostructure.bareprotostructure.BareProtostructure
- httk.atomistic.symmetry.canonical.canonicalize(structure: httk.atomistic.models.prototype.backend.PrototypeBackend, *, symmetry: Literal['detect', 'declared'] = 'detect', tolerance: float | None = None, factors: tuple[fractions.Fraction | float | int, ...] = (Fraction(1, 5), 1, 5), preserve_chirality: bool = True, timeout: float | None = 120.0) httk.atomistic.models.prototype.prototype.Prototype
- httk.atomistic.symmetry.canonical.canonicalize(structure: httk.atomistic.models.protostructure.backend.ProtostructureBackend, *, symmetry: Literal['detect', 'declared'] = 'detect', tolerance: float | None = None, factors: tuple[fractions.Fraction | float | int, ...] = (Fraction(1, 5), 1, 5), preserve_chirality: bool = True, timeout: float | None = 120.0) httk.atomistic.models.protostructure.protostructure.Protostructure
- httk.atomistic.symmetry.canonical.canonicalize(structure: httk.atomistic.models.structure.like.StructureLike, *, symmetry: Literal['detect', 'declared'] = 'detect', tolerance: float | None = None, factors: tuple[fractions.Fraction | float | int, ...] = (Fraction(1, 5), 1, 5), preserve_chirality: bool = True, timeout: float | None = 120.0) httk.atomistic.models.structure.asu.ASUStructure
Canonicalize a structure or classification without general upward symmetry search.
Structure inputs use anonymous framing, spglib recognition, and the exact protostructure terminal.
symmetry="declared"instead uses an already materialized ASU’s symmetry without recognition. Classification inputs use their available group/occupation information and transform carried examples. Their result has the corresponding classification type. No return value is selected from a time-truncated candidate set.canonical_asuis an alias.- Parameters:
structure – A structure-like source or one of the four classification families.
symmetry –
"detect"for structure recognition, or"declared"for an exact ASU. Classification values always use their carried symmetry model.tolerance – Cartesian recognition tolerance, or the precision-derived default. Only valid for structure recognition.
factors – Multipliers in the recognition tolerance sweep; only default values are accepted outside structure recognition.
preserve_chirality – Whether to retain enantiomorphic handedness.
timeout – Cooperative seconds for the operation;
Nonedisables the deadline. A native call or individual arithmetic operation cannot be preempted.
- Returns:
An ASUStructure for structure inputs, or the matching standalone classification.
- Raises:
CanonicalizationLimitError – If the operation exceeds its limit; no partial result is returned.
TypeError – If declared mode is given an input without a materialized exact ASU.
ValueError – If options or the input are unsupported, or recognition fails.
ImportError – If structure recognition requires unavailable spglib.
- httk.atomistic.symmetry.canonical.canonical_asu¶