Symmetry libraries¶
Per-topology point-group libraries, the node-centre library, space groups (spglib) and primitive cells: cage_isomer_builder.utils.symmetry.
tet2di4_transformation_library ¶
D4h: 4-fold z rotations and 4 cosets, 15 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D4h") # a perfectly D4h-symmetric test set
>>> library = symmetry.tet2di4_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(16, 16)
Source code in cage_isomer_builder/utils/symmetry.py
tet3_3di3_transformation_library ¶
D3h: 3-fold z rotations and 4 cosets, 11 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D3h") # a perfectly D3h-symmetric test set
>>> library = symmetry.tet3_3di3_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(12, 12)
Source code in cage_isomer_builder/utils/symmetry.py
tet4_4di8_transformation_library ¶
D4h: 4-fold z rotations and 4 cosets, 15 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D4h") # a perfectly D4h-symmetric test set
>>> library = symmetry.tet4_4di8_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(16, 16)
Source code in cage_isomer_builder/utils/symmetry.py
tet5di10_transformation_library ¶
D5h: 5-fold z rotations and 4 cosets, 19 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D5h") # a perfectly D5h-symmetric test set
>>> library = symmetry.tet5di10_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(20, 20)
Source code in cage_isomer_builder/utils/symmetry.py
tet6di12_transformation_library ¶
Oh: 47 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Oh") # a perfectly Oh-symmetric test set
>>> library = symmetry.tet6di12_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(48, 48)
Source code in cage_isomer_builder/utils/symmetry.py
tet8di16_transformation_library ¶
D4d: two sets of 4-fold z rotations, the second offset by a z flip and a 45-degree turn, and a YZ-plane reflection; 15 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D4d") # a perfectly D4d-symmetric test set
>>> library = symmetry.tet8di16_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(16, 16)
Source code in cage_isomer_builder/utils/symmetry.py
tet16di32_transformation_library ¶
D4h: 4-fold z rotations and 4 cosets, 15 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D4h") # a perfectly D4h-symmetric test set
>>> library = symmetry.tet16di32_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(16, 16)
Source code in cage_isomer_builder/utils/symmetry.py
tet24di48_transformation_library ¶
Oh: 47 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Oh") # a perfectly Oh-symmetric test set
>>> library = symmetry.tet24di48_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(48, 48)
Source code in cage_isomer_builder/utils/symmetry.py
tri2di3_transformation_library ¶
D3h: 3-fold z rotations and 4 cosets, 11 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D3h") # a perfectly D3h-symmetric test set
>>> library = symmetry.tri2di3_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(12, 12)
Source code in cage_isomer_builder/utils/symmetry.py
tri4di6_transformation_library ¶
Td: the full tetrahedral group, from the four node-centre positions.
All 24 permutations of the node centres are tried; SVD gives the matching 3x3 transformation, which is applied to the FG anchors. No determinant correction is applied, so the improper operations (sigma_d, S4) are included and the full Td group is obtained.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fg_anchor
|
Atoms
|
|
required |
rotation_axes
|
(array - like, shape(4, 3))
|
Positions of the four node centres. |
required |
Returns:
| Type | Description |
|---|---|
list of tuple
|
Slot-major transformation library, 23 non-identity operations. |
Examples:
>>> import numpy as np
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Td") # a perfectly Td-symmetric test set
>>> library = symmetry.tri4di6_transformation_library(anchors, 5 * np.array([[1, 1, 1], [1, -1, -1], [-1, 1, -1], [-1, -1, 1]]))
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(24, 24)
Source code in cage_isomer_builder/utils/symmetry.py
tri4_2di6_transformation_library ¶
D2h: 2-fold z rotations and 4 cosets, 7 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D2h") # a perfectly D2h-symmetric test set
>>> library = symmetry.tri4_2di6_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(8, 8)
Source code in cage_isomer_builder/utils/symmetry.py
tri6di9_transformation_library ¶
D3h: 3-fold z rotations and 4 cosets, 11 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D3h") # a perfectly D3h-symmetric test set
>>> library = symmetry.tri6di9_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(12, 12)
Source code in cage_isomer_builder/utils/symmetry.py
tri8di12_transformation_library ¶
Oh: 47 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Oh") # a perfectly Oh-symmetric test set
>>> library = symmetry.tri8di12_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(48, 48)
Source code in cage_isomer_builder/utils/symmetry.py
tri20di30_transformation_library ¶
Ih: the icosahedral group (order 120), 119 non-identity operations.
Generated from two 72-degree rotations about adjacent C5 axes of the icosahedron, (0, phi, 1) and (0, -phi, 1), and the inversion, and closed explicitly.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Ih") # a perfectly Ih-symmetric test set
>>> library = symmetry.tri20di30_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(120, 120)
Source code in cage_isomer_builder/utils/symmetry.py
tet6tri8_transformation_library ¶
Oh: same symmetry as tri8di12.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Oh") # a perfectly Oh-symmetric test set
>>> library = symmetry.tet6tri8_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(48, 48)
Source code in cage_isomer_builder/utils/symmetry.py
tri4tri4_transformation_library ¶
Td: same symmetry as tri4di6.
Examples:
>>> import numpy as np
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Td") # a perfectly Td-symmetric test set
>>> library = symmetry.tri4tri4_transformation_library(anchors, 5 * np.array([[1, 1, 1], [1, -1, -1], [-1, 1, -1], [-1, -1, 1]]))
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(24, 24)
Source code in cage_isomer_builder/utils/symmetry.py
tri1tri1_transformation_library ¶
C3v: 3-fold z rotations and 2 cosets (E and sigma_v), 5 non-identity operations.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> library = symmetry.tri1tri1_transformation_library(symmetry.ideal_orbit("D3h"))
>>> len(library[0]) + 1 # operations incl. identity
6
Source code in cage_isomer_builder/utils/symmetry.py
tri2_2tri2_transformation_library ¶
D2h: same symmetry as tri4_2di6.
Examples:
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("D2h") # a perfectly D2h-symmetric test set
>>> library = symmetry.tri2_2tri2_transformation_library(anchors)
>>> len(library), len(library[0]) + 1 # slots, operations incl. identity
(8, 8)
Source code in cage_isomer_builder/utils/symmetry.py
ideal_orbit ¶
A perfectly symmetric test structure: the orbit of one generic point
under an ideal point group, as X atoms, in the orientation the
per-topology libraries of this module assume (principal axis z, a
vertical mirror with normal x; Td/Oh/Ih in their standard cubic
setting). Every point is at least 2.5 Angstrom from every other, so
anchor matching is unambiguous.
Use it to check a transformation library: on the orbit, a correct
library returns exactly |G| - 1 non-identity operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group
|
(D2h, D3h, D4h, D5h, D4d, Td, Oh, Ih)
|
|
"D2h"
|
radius
|
float
|
Distance of the points from the origin (Angstrom). |
12.0
|
seed
|
int
|
Chooses the generic point. |
0
|
Returns:
| Type | Description |
|---|---|
Atoms
|
|
Examples:
>>> from cage_isomer_builder.utils.symmetry import ideal_orbit
>>> len(ideal_orbit("D4h")), len(ideal_orbit("Ih"))
(16, 120)
Source code in cage_isomer_builder/utils/symmetry.py
universal_transformation_library ¶
Transformation library from the node-centre positions.
Works for any topology whose point group acts faithfully on the node centres, i.e. no non-identity operation fixes every centre:
- 4 nodes at tetrahedral vertices (Td, 23 non-identity operations)
- 6 nodes at octahedral vertices (Oh, 47 non-identity operations)
- 8 nodes at cube vertices (Oh, 47 non-identity operations)
Prism and bipyramid topologies have operations that fix all node centres (e.g. the C4 rotation of a D4h bipyramid), which this function cannot see; use their topology-specific library.
Algorithm
For every permutation of the N node centres:
- Compute the best-fit orthogonal transformation by SVD.
- Keep it only if every transformed centre lands within
tolof its target. - Apply it to the FG anchors and record the permutation.
- Remove duplicates and the identity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fg_anchor
|
Atoms
|
|
required |
node_centers
|
(array - like, shape(N, 3))
|
Node centres, N at most 8. |
required |
tol
|
float
|
Matching tolerance (Angstrom). |
0.5
|
Returns:
| Type | Description |
|---|---|
list of tuple
|
Slot-major transformation library. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the centres lie on a line or in a plane, or there are more than 8. |
Examples:
>>> import numpy as np
>>> from cage_isomer_builder.utils import symmetry
>>> anchors = symmetry.ideal_orbit("Oh")
>>> octahedron = 5 * np.vstack([np.eye(3), -np.eye(3)]) # six node centres
>>> library = symmetry.universal_transformation_library(anchors, octahedron)
>>> len(library[0]) + 1
48
Source code in cage_isomer_builder/utils/symmetry.py
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 | |
spglib_dataset ¶
spglib symmetry dataset of a periodic structure, or None if spglib finds none at this tolerance.
Examples:
>>> from cage_isomer_builder import example_data
>>> from cage_isomer_builder.utils.symmetry import spglib_dataset
>>> spglib_dataset(example_data.read("RUBTAK01")).international
'Fm-3m'
Source code in cage_isomer_builder/utils/symmetry.py
primitive_cell ¶
The primitive cell of a periodic structure: the smallest cell that repeats to give the whole crystal (via spglib).
The atom positions are kept as they are (not moved to ideal symmetric
positions), so the geometry is unchanged. Only the cell, positions and
elements are kept; other per-atom arrays and info are dropped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
atoms
|
Atoms
|
Periodic structure. |
required |
symprec
|
float
|
spglib symmetry tolerance, the same default as
:func: |
1e-2
|
Returns:
| Type | Description |
|---|---|
Atoms
|
The primitive cell. If |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Examples:
>>> from cage_isomer_builder import example_data
>>> from cage_isomer_builder.utils.symmetry import primitive_cell
>>> uio66 = example_data.read("RUBTAK01") # conventional fcu cell
>>> len(uio66), len(primitive_cell(uio66)) # four lattice points per cell
(440, 110)
Source code in cage_isomer_builder/utils/symmetry.py
spacegroup_transformation_library ¶
Transformation library of a periodic structure from its space group (spglib).
A unit cell's FG anchors are related by the full space group, including translations, screw axes and glide planes. A point group about one centre misses most of these operations, so a periodic structure must use this function.
Algorithm
- Get every (rotation, translation) operation of the space group from spglib, in fractional coordinates.
- Apply each operation to the anchors' fractional positions and match every image to the anchor it coincides with (minimum image).
- Remove the identity and duplicate permutations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cage_atoms
|
Atoms
|
The full periodic structure (with |
required |
fg_anchor_indices
|
sequence of int
|
Indices of the FG anchors in |
required |
symprec
|
float
|
spglib tolerance. Real, slightly noisy structures usually need a looser value than spglib's default of 1e-5. |
1e-2
|
atom_tol
|
float
|
Distance (Angstrom) within which an image matches an anchor. Anchors are always much further apart than this. |
0.5
|
Returns:
| Type | Description |
|---|---|
list of tuple
|
Slot-major transformation library, in the same format as universal_transformation_library. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If spglib finds no space group, or an operation does not map the
anchors onto themselves within |
Examples:
>>> from cage_isomer_builder import example_data
>>> from cage_isomer_builder.utils.symmetry import primitive_cell, spacegroup_transformation_library
>>> cell = primitive_cell(example_data.read("RUBTAK01"))
>>> zr = [a.index for a in cell if a.symbol == "Zr"]
>>> library = spacegroup_transformation_library(cell, zr) # how the 6 Zr permute
>>> len(library), len(library[0]) + 1 # Fm-3m: 48 point operations
(6, 48)
Source code in cage_isomer_builder/utils/symmetry.py
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 | |