Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
for params in found_params:
order = params[0]
op_type = params[1]
if op_type == "rotation" and (order == 3 or order == 6):
m = aa2matrix(op_axis, (2*pi)/order)
elif op_type == "improper rotation" and (order == 3 or order == 6):
m = aa2matrix(op_axis, (2*pi)/order)
m[2] *= -1
symm_point_partial.append(SymmOp.from_rotation_and_translation(m, [0,0,0]))
#print("Generating...")
symm_point = generate_full_symmops(symm_point_partial, 1e-2)
#print("Done")
for op in symm_point:
site_symmetry[sg][-1][-1].append(op.as_xyz_string())"""
P = SymmOp.from_rotation_and_translation(
[[1, -0.5, 0], [0, sqrt(3) / 2, 0], [0, 0, 1]], [0, 0, 0]
)
site_symmetry = [None]
# site_symm is stored by space group number starting with 1 (site_symm[1] is P1))
print("Calculating space group:")
for sg in range(1, 231):
print(sg)
site_symmetry.append([])
symm_sg = get_wyckoff_symmetry(sg)
# Get site symmetry for every point in each wp, and store
for i, symm_wp in enumerate(symm_sg):
site_symmetry[sg].append([])
for j, symm_point in enumerate(symm_wp):
site_symmetry[sg][-1].append([])
for op in symm_point:
Return symmetry operations as a list of SymmOp objects.
By default returns fractional coord symmops.
But cartesian can be returned too.
Returns:
([SymmOp]): List of symmetry operations.
"""
rotation, translation = self._get_symmetry()
symmops = []
mat = self._structure.lattice.matrix.T
invmat = np.linalg.inv(mat)
for rot, trans in zip(rotation, translation):
if cartesian:
rot = np.dot(mat, np.dot(rot, invmat))
trans = np.dot(trans, self._structure.lattice.matrix)
op = SymmOp.from_rotation_and_translation(rot, trans)
symmops.append(op)
return symmops
#Ensure the identity orientation is checked if no constraints are found
if constraints_m == []:
o = orientation(np.identity(3), degrees=2)
orientations.append(o)
#Remove redundancy from orientations
list_i = list(range(len(orientations)))
list_j = list(range(len(orientations)))
for i , o1 in enumerate(orientations):
if i in list_i:
for j , o2 in enumerate(orientations):
if i > j and j in list_j and j in list_i:
m1 = o1.get_matrix(angle=0)
m2 = o2.get_matrix(angle=0)
new_op = SymmOp.from_rotation_and_translation(np.dot(m2, np.linalg.inv(m1)), [0,0,0])
P = SymmOp.from_rotation_and_translation(np.linalg.inv(m1), [0,0,0])
old_op = P*new_op*P.inverse
if pga.is_valid_op(old_op):
list_i.remove(j)
list_j.remove(j)
copy = deepcopy(orientations)
orientations = []
for i in list_i:
orientations.append(copy[i])
#Check each of the found orientations for consistency with the Wyckoff pos.
#If consistent, put into an array of valid orientations
allowed = []
for o in orientations:
if randomize is True:
op = o.get_op()
elif randomize is False:
logger.debug("Done testing in {} secs".format(time.time() - \
self._start_time))
self._atomic_misfit = biggest_dist / ((3 * 0.7405 * a.volume / \
(4 * math.pi * a.num_sites)) ** (1 / 3))
if mapping_op != None:
rot = mapping_op.rotation_matrix # maps to_fit to fixed
p = sqrt_matrix(np.dot(rot.transpose(), rot))
scale_matrix = np.eye(3) * self.scale
newrot = np.dot(scale_matrix, rot)
# we need to now make sure fitterdata.MappingOp maps b -> a and not
# the other way around
mshift = np.dot(rot, oshift.translation_vector)
finaltranslation = mapping_op.translation_vector + mshift[0]
composite_op = SymmOp.from_rotation_and_translation(
newrot, finaltranslation)
self._mapping_op = composite_op if self.fixed_is_a \
else composite_op.inverse
#self._mapping_op = mapping_op
self._cell_misfit = shear_invariant(p)
#Check that the displacement is less than tol
displacement = difference.translation_vector
if distance(displacement, lattice) > tol:
is_symmetry = False
if is_symmetry:
'''The actual site symmetry's translation vector may vary from op by
a factor of +1 or -1 (especially when op contains +-1/2).
We record this to distinguish between special Wyckoff positions.
As an example, consider the point (-x+1/2,-x,x+1/2) in position 16c
of space group Ia-3(206). The site symmetry includes the operations
(-z+1,x-1/2,-y+1/2) and (y+1/2,-z+1/2,-x+1). These operations are
not listed in the general position, but correspond to the operations
(-z,x+1/2,-y+1/2) and (y+1/2,-z+1/2,-x), respectively, just shifted
by (+1,-1,0) and (0,0,+1), respectively.
'''
el = SymmOp.from_rotation_and_translation(op.rotation_matrix, op.translation_vector - np.round(displacement))
symmetry.append(el)
return symmetry
def reorient(mol):
new_mol = mol.get_centered_molecule()
A = get_inertia_tensor(new_mol)
#Store the eigenvectors of the inertia tensor
P = np.transpose(eigh(A)[1])
if det(P) < 0:
P[0] *= -1
#reorient the molecule
P = SymmOp.from_rotation_and_translation(P,[0,0,0])
new_mol.apply_operation(P)
#Our molecule should never be inverted during reorientation.
if det(P.rotation_matrix) < 0:
print("Error: inverted reorientation applied.")
return new_mol, P
#If needed, recursively apply reorientation (due to numerical errors)
def get_symmetry_operations(self, cartesian=False):
"""
Return symmetry operations as a list of SymmOp objects.
By default returns fractional coord symmops.
But cartesian can be returned too.
"""
(rotation, translation) = self._get_symmetry()
symmops = []
mat = self._structure.lattice.matrix.T
invmat = np.linalg.inv(mat)
for rot, trans in zip(rotation, translation):
if cartesian:
rot = np.dot(mat, np.dot(rot, invmat))
trans = np.dot(trans, self._structure.lattice.matrix)
op = SymmOp.from_rotation_and_translation(rot, trans)
symmops.append(op)
return symmops
z-axis relaxation.
Args:
structure (Structure): Pymatgen Structure object to rotate.
Returns:
structure. Rotated to align c-axis along [001].
"""
c = structure.lattice._matrix[2]
z = [0, 0, 1]
axis = np.cross(c, z)
if not(axis[0] == 0 and axis[1] == 0):
theta = (np.arccos(np.dot(c, z) / (np.linalg.norm(c) * np.linalg.norm(z))))
R = get_rotation_matrix(axis, theta)
rotation = SymmOp.from_rotation_and_translation(rotation_matrix=R)
structure.apply_operation(rotation)
return structure
logger.debug("Done testing in {} secs".format(time.time() - \
self._start_time))
self._atomic_misfit = biggest_dist / ((3 * 0.7405 * a.volume / \
(4 * math.pi * a.num_sites)) ** (1 / 3))
if mapping_op != None:
rot = mapping_op.rotation_matrix # maps to_fit to fixed
p = sqrt_matrix(np.dot(rot.transpose(), rot))
scale_matrix = np.eye(3) * self.scale
newrot = np.dot(scale_matrix, rot)
# we need to now make sure fitterdata.MappingOp maps b -> a and not
# the other way around
mshift = np.dot(rot, oshift.translation_vector)
finaltranslation = mapping_op.translation_vector + mshift[0]
composite_op = SymmOp.from_rotation_and_translation(
newrot, finaltranslation)
self._mapping_op = composite_op if self.fixed_is_a \
else composite_op.inverse
#self._mapping_op = mapping_op
self._cell_misfit = shear_invariant(p)
def _test_rotation(self, rot, origin, fixed, to_fit, tol_atoms):
tol_atoms_plus = 1.1 * tol_atoms
found_map = False
mapping_op = None
biggest_dist = 0
logger.debug("Trying candidate rotation : \n" + str(rot))
for site in fixed:
if time.time() - self._start_time > self._timeout:
logger.debug("Timeout reached when testing rotations.")
break
if site.species_and_occu == origin.species_and_occu:
shift = site.coords
op = SymmOp.from_rotation_and_translation(
rot.rotation_matrix, shift)
nstruct = apply_operation(to_fit, op)
correspondance = OrderedDict()
all_match = True
biggest_dist = 0
# check to see if transformed struct matches fixed structure
for trans in nstruct:
cands = fixed.get_sites_in_sphere(trans.coords,
tol_atoms_plus)
if len(cands) == 0:
logger.debug("No candidates found.")
all_match = False
break
cands = sorted(cands, key=lambda a: a[1])
(closest, closest_dist) = cands[0]
if closest_dist > tol_atoms or \