Skip to content

Commit a0ec81c

Browse files
committed
ENH: add function FindSpaceGroup
Find space group from a list of symmetry operations.
1 parent 3ddf778 commit a0ec81c

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/diffpy/structure/spacegroups.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,45 @@ def IsSpaceGroupIdentifier(sgid):
7373
return rv
7474

7575

76+
def FindSpaceGroup(symops, shuffle=False):
77+
"""Lookup SpaceGroup from a given list of symmetry operations.
78+
79+
Parameters
80+
----------
81+
symops : list
82+
The list of `SymOp` objects for which to find SpaceGroup.
83+
shuffle : bool, optional
84+
Flag for allowing different order of symops in the returned
85+
SpaceGroup. The default is ``False``.
86+
87+
Returns
88+
-------
89+
SpaceGroup
90+
The SpaceGroup object with equivalent list of symmetry
91+
operations. Return predefined SpaceGroup instance when
92+
symmetry operations have the same order or when the
93+
`shuffle` flag is set.
94+
95+
Raises
96+
------
97+
ValueError
98+
When `symops` do not match any known SpaceGroup.
99+
"""
100+
import copy
101+
from six.moves import zip_longest
102+
tb = _getSGHashLookupTable()
103+
hh = _hashSymOpList(symops)
104+
if not hh in tb:
105+
raise ValueError('Cannot find SpaceGroup for the specified symops.')
106+
rv = tb[hh]
107+
if not shuffle:
108+
zz = zip_longest(rv.iter_symops(), symops, fillvalue='')
109+
sameorder = all(str(o0) == str(o1) for o0, o1 in zz)
110+
if not sameorder:
111+
rv = copy.copy(rv)
112+
return rv
113+
114+
76115
def _hashSymOpList(symops):
77116
"""Return hash value for a sequence of `SymOp` objects.
78117
@@ -136,6 +175,19 @@ def _buildSGLookupTable():
136175
return
137176
_sg_lookup_table = {}
138177

178+
179+
def _getSGHashLookupTable():
180+
"""Return lookup table of symop hashes to standard SpaceGroup objects.
181+
"""
182+
if _sg_hash_lookup_table:
183+
return _sg_hash_lookup_table
184+
for sg in SpaceGroupList:
185+
h = _hashSymOpList(sg.symop_list)
186+
_sg_hash_lookup_table[h] = sg
187+
assert len(_sg_hash_lookup_table) == len(SpaceGroupList)
188+
return _getSGHashLookupTable()
189+
_sg_hash_lookup_table = {}
190+
139191
# Import SpaceGroup objects --------------------------------------------------
140192

141193
from diffpy.structure.spacegroupmod import (

src/diffpy/structure/tests/testspacegroups.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import unittest
2121

2222
from diffpy.structure.spacegroups import SpaceGroupList, _hashSymOpList
23+
from diffpy.structure.spacegroups import GetSpaceGroup, FindSpaceGroup
2324

2425
# ----------------------------------------------------------------------------
2526

@@ -29,6 +30,21 @@ def setUp(self):
2930
return
3031

3132

33+
def test_FindSpaceGroup(self):
34+
"check FindSpaceGroup function"
35+
sg123 = GetSpaceGroup(123)
36+
ops123 = list(sg123.iter_symops())
37+
self.assertRaises(ValueError, FindSpaceGroup, [])
38+
self.assertRaises(ValueError, FindSpaceGroup, 2 * ops123)
39+
self.assertIs(sg123, FindSpaceGroup(ops123))
40+
sg123r = FindSpaceGroup(ops123[::-1])
41+
self.assertIsNot(sg123, sg123r)
42+
self.assertEqual(_hashSymOpList(sg123.symop_list),
43+
_hashSymOpList(sg123r.symop_list))
44+
self.assertIs(sg123, FindSpaceGroup(ops123[::-1], shuffle=True))
45+
return
46+
47+
3248
def test__hashSymOpList(self):
3349
"verify _hashSymOpList is unique for each spacegroup"
3450
hset = set(_hashSymOpList(sg.symop_list) for sg in SpaceGroupList)

0 commit comments

Comments
 (0)