def check_n_two_fold_perpendicular_to_n_fold(self, rotation_symmetry):
     principal_axis = self.return_principal_axis(rotation_symmetry)
     axis_of_rotation = []
     for rotation in rotation_symmetry:
         if principal_axis != rotation and rotation.fold == 2 and (theta(rotation.vector) - pi/2 <= self.error):
             axis_of_rotation.append(rotation.vector)
     if len(axis_of_rotation) == principal_axis.fold:
         return True
     else:
         return False
    def standard_orientation(self, nuclei_array, rotation_symmetry, reflection_symmetry):
        vector_i = vector_j = (0.0, 0.0, 0.0)

        if len(rotation_symmetry) > 1:
            highest_n_folds = heapq.nlargest(2, [rotation.fold for rotation in rotation_symmetry])
            for rotation in rotation_symmetry:
                if rotation.fold == highest_n_folds[0]:
                    vector_i = rotation.vector
                    break
            for rotation in rotation_symmetry:
                if rotation.fold == highest_n_folds[1] and rotation.vector != vector_i:
                    vector_j = rotation.vector
                    break

        if len(rotation_symmetry) == 1:
            vector_i = rotation_symmetry[0].vector
            for reflection in reflection_symmetry:
                if phi(reflection.vector) > self.error:
                    vector_j = reflection.vector
                    break

        if len(rotation_symmetry) == 0 and len(reflection_symmetry) > 1:
            vector_i = reflection_symmetry[0].vector
            vector_j = reflection_symmetry[1].vector

        if rho(nuclei_array[0].coordinates) > 1e-3:
            i = 0
        else:
            i = 1

        if len(rotation_symmetry) == 0 and len(reflection_symmetry) == 1:
            vector_i = reflection_symmetry[0].vector
            vector_j = nuclei_array[i].coordinates

        if len(rotation_symmetry) == 0 and len(reflection_symmetry) == 0:
            vector_i = nuclei_array[i].coordinates
            vector_j = nuclei_array[i + 1].coordinates

        if rho(vector_i) <= self.error:
            vector_i = (1.0, 0.0, 0.0)

        quaternion_i = create_quaternion((-vector_i[1], vector_i[0], 0.0), -theta(vector_i))
        quaternion_j = create_quaternion((0.0, 0.0, 1.0), -phi(vector_j))
        quaternion = quaternion_multi(quaternion_j, quaternion_i)

        for rotation in rotation_symmetry:
            rotation.vector = quaternion_rotation(quaternion, rotation.vector)
        for reflection in reflection_symmetry:
            reflection.vector = quaternion_rotation(quaternion, reflection.vector)
        for nuclei in nuclei_array:
            nuclei.coordinates = quaternion_rotation(quaternion, nuclei.coordinates)
 def return_principal_axis(self, rotation_symmetry):
     for rotation in rotation_symmetry:
         if theta(rotation.vector) % pi <= self.error:
             return rotation
 def check_linear(self, nuclei_array):
     for nuclei in nuclei_array:
         if theta(nuclei.coordinates) % pi > self.error:
             return False
     return True
 def check_sigma_h(self, reflection_symmetry):
     for reflection in reflection_symmetry:
         if theta(reflection.vector) % pi <= self.error:
             return True
     return False