[docs]classSymmetryOperation(abc.ABC):"""An abstract base class for symmetry operations."""
[docs]@abc.abstractmethoddeftransform(self,structure:ase.Atoms)->ase.Atoms:"Subclasses should override this method."
[docs]classRotation(SymmetryOperation):"""A rotation operation. Attributes: angle: A float specifying a rotation angle in degrees. axis: A numpy.array representing the axis of rotation. """def__init__(self,angle:float,axis:Iterable[float])->None:"""Create a rotation symmetry operation. Args: angle: The angle of rotation. axis: The axis of rotation. """self.angle=angleself.axis=np.array(axis)
[docs]deftransform(self,structure:ase.Atoms)->ase.Atoms:"""Rotate a structure. This retthe given structure by the angle and about the axis specified as attributes of the Rotation object. Args: structure: An :class:`.atoms.Atoms` instance representing structure to be rotated. Returns: A copy of the original :class:`.atoms.Atoms` instance rotated by :attr:`Rotation.angle` about the axis :attr:`Rotation.axis`. """new_structure=structure.copy()new_structure.rotate(self.angle,self.axis)returnnew_structure
[docs]defas_matrix(self)->np.ndarray:"""The rotation matrix of the symmetry operation."""rotvec=self.angle*(self.axis/norm(self.axis))rotation=transform.Rotation.from_rotvec(rotvec,degrees=True)returnrotation.as_matrix()
[docs]classSymmetry(abc.ABC):"""An abstract base class for molecule symmetries."""@property@abc.abstractmethoddefoperation(self)->SymmetryOperation:"Subclasses should override this method."
[docs]@abc.abstractmethoddefcheck_symmetry(self,structure:ase.Atoms,tol:float)->bool:"Subclasses should override this method."
[docs]classRotationSymmetry(Symmetry):"""A rotational symmetry."""def__init__(self,operation:Rotation)->None:"""Create a rotation symmetry. Args: operation: A rotation operation. """self._operation=operation@propertydefoperation(self)->Rotation:"""The :class:`Rotation` associated with the symmetry."""returnself._operation
[docs]defcheck_symmetry(self,structure:ase.Atoms,tol:float=5e-2)->bool:"""Check if the symmetry belongs to the structure's symmetry group. Args: structure: An :class:`.atoms.Atoms` instance representing the structure whose symmetry is to be determined. tol: A float specifying the absolute tolerance for positions. Defaults to 5e-2. Returns: A bool indicating whether or not the given structure possesses the symmetry of the :class:`RotationSymmetry` object subject to the specified tolerance. """old_structure=structure# Rotate structurerotated_structure=self._operation.transform(structure)# Check for similarity wrt. tolerancereturncomparator.Comparator.check_similarity(old_structure,rotated_structure,tol=tol)