def is_dihedral(self): """ Whether or not the reflection is a sigma_d """ if self.principal_reflection: return False for atom in self.molecule: # If there's an atom in the plane, it's a sigma_v. If there's an atom in the direction of the normal (or it's negative), # it's sigma_v. Otherwise, it's a sigma_d. If the atom is at the origin, ignore it. if atom.pos.is_zero(): continue elif SymmetryOperation.is_same_axis(self.axis, atom.pos): return False elif SymmetryOperation.is_perpendicular(self.axis, atom.pos): return False return True
def is_dihedral(self): """ Whether or not the reflection is a sigma_d """ if self.principal_reflection: return False for atom in self.molecule: # If there's an atom in the plane, it's a sigma_v. If there's an atom in the direction of the normal (or it's negative), # it's sigma_v. Otherwise, it's a sigma_d. If the atom is at the origin, ignore it. if atom.pos.is_zero(): continue elif SymmetryOperation.is_same_axis(self.axis, atom.pos): return False elif SymmetryOperation.is_perpendicular(self.axis, atom.pos): return False return True
def _name_operations(self): """ Determines the most-likely-to-be human-readable names for the operations. """ # Figure out the principal reflections (sigma_h's) principal_rotations = [] for k, g in itertools.groupby(sorted(self.rotations), attrgetter('n', 'exponent')): principal_rotations = list(g) break if len(principal_rotations) > 0: if principal_rotations[0].n > 2: # Mark them all as sigma_h's for rot in principal_rotations: for op in self.reflections: if SymmetryOperation.is_same_axis(op.axis, rot.axis): op.principal_reflection = True else: # Otherwise, just choose the Z axis for op in self.reflections: if SymmetryOperation.is_same_axis( op.axis, principal_rotations[0].axis): op.principal_reflection = True break self.operations.sort() self._rotations = None self._improper_rotations = None self._reflections = None self.identity_element.name = "E" if not self.inversion is None: self.inversion.name = 'i' for key, rotiter in itertools.groupby(self.rotations, attrgetter('n')): rotgrp = list(rotiter) prime_count = 0 labels = [] order = rotgrp[0].n if len(rotgrp) == rotgrp[0].n - 1: # only one axis, label it simply rotgrp[0].name = "C_" + str(order) for i in xrange(1, len(rotgrp)): rotgrp[i].name = "C_" + str(order) + "^" + str( rotgrp[i].exponent) else: naxes = len([x for x in rotgrp if x.exponent == 1]) has_paren_label = False for i, rot in enumerate(rotgrp): if i < naxes: if SymmetryOperation.is_same_axis( rot.axis, Vector(0, 0, 1)): labels.append("(z)") has_paren_label = True rot.name = "C_" + str(order) + "(z)" elif SymmetryOperation.is_same_axis( rot.axis, Vector(0, 1, 1)): labels.append("(y)") has_paren_label = True rot.name = "C_" + str(order) + "(y)" elif SymmetryOperation.is_same_axis( rot.axis, Vector(1, 0, 0)): labels.append("(x)") has_paren_label = True rot.name = "C_" + str(order) + "(x)" else: label = "'" * (prime_count + (1 if has_paren_label else 0)) labels.append(label) prime_count += 1 rot.name = "C_" + str(order) + label else: rot.name = "C_" + str(order) + labels[ i % naxes] + "^" + str(rot.exponent) for key, rotiter in itertools.groupby(self.improper_rotations, attrgetter('n')): rotgrp = list(rotiter) prime_count = 0 labels = [] order = rotgrp[0].n if len(rotgrp) == rotgrp[0].n - 1: # only one axis, label it simply rotgrp[0].name = "S_" + str(order) for i in xrange(1, len(rotgrp)): rotgrp[i].name = "S_" + str(order) + "^" + str( rotgrp[i].exponent) else: has_paren_label = False naxes = len([x for x in rotgrp if x.exponent == 1]) for i, rot in enumerate(rotgrp): if i < naxes: if SymmetryOperation.is_same_axis( rot.axis, Vector(0, 0, 1)): labels.append("(z)") has_paren_label = True rot.name = "S_" + str(order) + "(z)" elif SymmetryOperation.is_same_axis( rot.axis, Vector(0, 1, 0)): labels.append("(y)") has_paren_label = True rot.name = "S_" + str(order) + "(y)" elif SymmetryOperation.is_same_axis( rot.axis, Vector(1, 0, 0)): labels.append("(x)") has_paren_label = True rot.name = "S_" + str(order) + "(x)" else: label = "'" * (prime_count + (1 if has_paren_label else 0)) labels.append(label) prime_count += 1 rot.name = "S_" + str(order) + label else: rot.name = "S_" + str(order) + labels[ i % naxes] + "^" + str(rot.exponent) prime_count = {'v': 0, 'd': 0, 'h': 0} has_paren_label = False for ref in self.reflections: subscript = '' if ref.is_principal_reflection(): subscript = 'h' elif ref.is_dihedral(): subscript = 'd' else: subscript = 'v' if SymmetryOperation.is_same_axis(ref.axis, Vector(0, 0, 1)): ref.name = "sigma_" + subscript + "(xy)" has_paren_label = True elif SymmetryOperation.is_same_axis(ref.axis, Vector(0, 1, 0)): ref.name = "sigma_" + subscript + "(xz)" has_paren_label = True elif SymmetryOperation.is_same_axis(ref.axis, Vector(1, 0, 0)): ref.name = "sigma_" + subscript + "(yz)" has_paren_label = True else: label = "'" * (prime_count[subscript] + (1 if has_paren_label else 0)) prime_count[subscript] += 1 ref.name = "sigma_" + subscript + label self.classes.sort(key=attrgetter('first_element'))
def _name_operations(self): """ Determines the most-likely-to-be human-readable names for the operations. """ # Figure out the principal reflections (sigma_h's) principal_rotations = [] for k, g in itertools.groupby(sorted(self.rotations), attrgetter('n', 'exponent')): principal_rotations = list(g) break if len(principal_rotations) > 0: if principal_rotations[0].n > 2: # Mark them all as sigma_h's for rot in principal_rotations: for op in self.reflections: if SymmetryOperation.is_same_axis(op.axis, rot.axis): op.principal_reflection = True else: # Otherwise, just choose the Z axis for op in self.reflections: if SymmetryOperation.is_same_axis(op.axis, principal_rotations[0].axis): op.principal_reflection = True break self.operations.sort() self._rotations = None self._improper_rotations = None self._reflections = None self.identity_element.name = "E" if not self.inversion is None: self.inversion.name = 'i' for key, rotiter in itertools.groupby(self.rotations, attrgetter('n')): rotgrp = list(rotiter) prime_count = 0 labels = [] order = rotgrp[0].n if len(rotgrp) == rotgrp[0].n - 1: # only one axis, label it simply rotgrp[0].name = "C_" + str(order) for i in xrange(1, len(rotgrp)): rotgrp[i].name = "C_" + str(order) + "^" + str(rotgrp[i].exponent) else: naxes = len([x for x in rotgrp if x.exponent == 1]) has_paren_label = False for i, rot in enumerate(rotgrp): if i < naxes: if SymmetryOperation.is_same_axis(rot.axis, Vector(0,0,1)): labels.append("(z)") has_paren_label = True rot.name = "C_" + str(order) + "(z)" elif SymmetryOperation.is_same_axis(rot.axis, Vector(0,1,1)): labels.append("(y)") has_paren_label = True rot.name = "C_" + str(order) + "(y)" elif SymmetryOperation.is_same_axis(rot.axis, Vector(1,0,0)): labels.append("(x)") has_paren_label = True rot.name = "C_" + str(order) + "(x)" else: label = "'" * (prime_count + (1 if has_paren_label else 0)) labels.append(label) prime_count += 1 rot.name = "C_" + str(order) + label else: rot.name = "C_" + str(order) + labels[i % naxes] + "^" + str(rot.exponent) for key, rotiter in itertools.groupby(self.improper_rotations, attrgetter('n')): rotgrp = list(rotiter) prime_count = 0 labels = [] order = rotgrp[0].n if len(rotgrp) == rotgrp[0].n - 1: # only one axis, label it simply rotgrp[0].name = "S_" + str(order) for i in xrange(1, len(rotgrp)): rotgrp[i].name = "S_" + str(order) + "^" + str(rotgrp[i].exponent) else: has_paren_label = False naxes = len([x for x in rotgrp if x.exponent == 1]) for i, rot in enumerate(rotgrp): if i < naxes: if SymmetryOperation.is_same_axis(rot.axis, Vector(0,0,1)): labels.append("(z)") has_paren_label = True rot.name = "S_" + str(order) + "(z)" elif SymmetryOperation.is_same_axis(rot.axis, Vector(0,1,0)): labels.append("(y)") has_paren_label = True rot.name = "S_" + str(order) + "(y)" elif SymmetryOperation.is_same_axis(rot.axis, Vector(1,0,0)): labels.append("(x)") has_paren_label = True rot.name = "S_" + str(order) + "(x)" else: label = "'" * (prime_count + (1 if has_paren_label else 0)) labels.append(label) prime_count += 1 rot.name = "S_" + str(order) + label else: rot.name = "S_" + str(order) + labels[i % naxes] + "^" + str(rot.exponent) prime_count = {'v':0, 'd':0,'h':0} has_paren_label = False for ref in self.reflections: subscript = '' if ref.is_principal_reflection(): subscript = 'h' elif ref.is_dihedral(): subscript = 'd' else: subscript = 'v' if SymmetryOperation.is_same_axis(ref.axis, Vector(0,0,1)): ref.name = "sigma_"+ subscript + "(xy)" has_paren_label = True elif SymmetryOperation.is_same_axis(ref.axis, Vector(0,1,0)): ref.name = "sigma_" + subscript + "(xz)" has_paren_label = True elif SymmetryOperation.is_same_axis(ref.axis, Vector(1,0,0)): ref.name = "sigma_" + subscript + "(yz)" has_paren_label = True else: label = "'" * (prime_count[subscript] + (1 if has_paren_label else 0)) prime_count[subscript] += 1 ref.name = "sigma_" + subscript + label self.classes.sort(key=attrgetter('first_element'))