SOFI interface
- class ira_mod.SOFI(shlib='')[source]
The Symmetry Operation FInder (SOFI) is an algorithm for finding point group symmetry operations of atomic structures. It solves the problem:
\[A = \theta A\]where \(A\) is an atomic structure, and \(\theta\) is a symmetry operation in the form of 3x3 orthonormal matrix.
The main result of SOFI is a list of operations \(\theta\). This list can be post-processed to obtain the point group name, and other properties associated to each \(\theta\).
For further details see the publication:
M Gunde, N Salles, L Grisanti, L Martin-Samos, A Hemeryck: J. Chem. Phys. 2024, 161, 6, 062503 DOI: https://doi.org/10.1063/5.0215689 arXiv: https://arxiv.org/abs/2408.06131
In order to use the module, the path to this file should be added to the environment variable PYTHONPATH:
export PYTHONPATH=/your/path/to/IRA/interface
Example import:
>>> import ira_mod >>> sofi = ira_mod.SOFI( )
- compute(nat, typ_in, coords, sym_thr, origin=None, prescreen_ih=False)[source]
this is a wrapper to libira_compute_all() from library_sofi.f90 Description: This routine computes all the relevant PG symmetry data of the input structure. Unless an origin point is specified, the input structure is shifted to the geometric center by this python interface.
== input: ==
- Parameters
nat (int) – number of atoms in the structure
typ_in (string or int) – atomic types of the atoms
coords (np.ndarray((nat,3), dtype=float)) – the atomic positions of the structure
sym_thr (float) – symmetry threshold value
== optional: ==
- Parameters
origin (np.ndarray(3, dtype=float)) – if specified, it will be taken as origin point, otherwise the geometric center is the origin
prescreen_ih – if True, force sofi to check for Ih group already during computation.
== output: ==
instance of
ira_mod.sym_data()
object, which cotains the full symmetry data of the input structure. See sym_data.object sym_data contains the full symmetry data of the input structure. To access info about symmetry element i, get the data as: sym_data.var[i], where var is one of the variables in the sym_data object:
n_sym, matrix, perm, op, n, p, axis, angle, dHausdorff, pg, prin_ax
see help( ira_mod.sym_data ) for full description of these variables.
- get_symm_ops(nat, typ_in, coords, sym_thr, prescreen_ih=False)[source]
Wrapper to the libira_get_symm_ops routine from library_sofi.f90. Description: finds the symmetry operation maytices of the structure in input, which fit the threshold sym_thr.
== input: ==
- Parameters
nat (int) – number of atoms in the structure
typ_in (string or int) – atomic types of the atoms
coords (np.ndarray((nat,3), dtype=float)) – the atomic positions of the structure
sym_thr (float) – symmetry threshold value
== optional ==
- Parameters
prescreen_ih – if True, force sofi to check for Ih group already during computation.
== output: ==
- Parameters
n_sym (int) – number of symmetry elements found
matrix (np.ndarray((n_sym, 3, 3), dtype = float)) – the list of matrices of symmetry operations
- get_pg(nm_in, mat_list, verb=False)[source]
wrapper to libira_get_pg() from library_sofi.f90 Description: find the PG of input list of operations. Returns also the list of all equivalent principal axes.
== input: ==
- Parameters
nm_in (integer) – number of matrices in the mat_list array
mat_list (np.ndarray( (nm_in, 3, 3), dtype = float )) – list of matrices containging symmetry operations
== optional ==
- Parameters
verb (logical) – verbosity of the output, verb=True outputs a report from get_pg() routine.
== output: ==
- Parameters
pg (string) – associated Point Group (PG)
n_prin_ax (integer) – number of equivalent principal axes
prin_ax (np.ndarray( (n_prin_ax, 3), dtype = float )) – list of principal axes of the PG
- get_unique_ax_angle(nm_in, mat_list)[source]
wrapper to libira_get_unique_ax_angle() from library_sofi.f90 Description: input list of symmetry matrices, output lists of op, ax, angle for each symmetry operation in the list, such that axes are aligned, and angle has a correspoding +/- sign.
This is a wrapper to libira_unique_ax_angle() routine from library_sofi.f90
== input: ==
- Parameters
nm_in (integer) – number of matrices in the mat_list array
mat_list (np.ndarray( (nm_in, 3, 3), dtype = float )) – list of matrices containging symmetry operations
== output: ==
- Parameters
op (array of length-1 strings, nd.ndarray( nm_in, dtype = "U1" )) – Schoeflies Op name, possible values: - “E” = identity - “I” = inversion - “C” = rotation - “S” = (roto-)reflection
axis (nm_in x 3 vector, np.ndarray((nm_in, 3), dtype = float)) – the list of axes along each corresponding matrix acts.
angle (np.ndarray( nm_in, dtype = float )) – the list of angles by which each matrix rotates, in units of 1/(2pi), e.g. the value angle = 0.5 means half the circle, and angle = -1.0/6.0 means rotation about the axis in negative direction for 1/6th of the circle
- analmat(rmat)[source]
Description: analyse the input matrix, output the Schoenflies notation: Op n^p, the axis, and angle. The notation can be transformed into an angle in radians, or degree:
angle_radian = p / n * 2pi angle_degree = p / n * 360
e.g. C 8^3 corresponds to 3/8th of full circle = 135 degress = 2.3563 radian, p/n = 0.375
This is a wrapper to libira_analmat() routine from library_sofi.f90
== input: ==
- Parameters
rmat (np.ndarray((3, 3), dtype = float )) – input matrix
== output: ==
- Parameters
op (string) – Schoeflies Op name, possible values: - “E” = identity - “I” = inversion - “C” = rotation - “S” = (roto-)reflection
n (integer) – the n value from Op n^p, gives the angle 2pi/n
p (integer) – the p value from Op n^p, gives the “multiplicity” of 1/n operation
ax (3D vector, np.ndarray(3, dtype = float)) – axis along which the matrix rmat operates, in case of rotation is the axis of rotation, in case of (roto-)reflection is the normal of the plane of reflection.
angle (np.float32) – the angle of rotation of matrix rmat, in units of 1/2pi, is the ratio p/n
- ext_Bfield(n_mat, mat_list, b_field)[source]
wrapper to libira_ext_Bfield() from library_sofi.f90 Description: Impose a constraint on the relevant symmetry operations, in the form of an external magnetic field as arbitrary vector.
Implementation of the functionality proposed in:
Ansgar Pausch, Melanie Gebele, Wim Klopper; Molecular point groups and symmetry in external magnetic fields. J. Chem. Phys. 28 November 2021; 155 (20): 201101. DOI: https://doi.org/10.1063/5.0069859
The magnetic field acts as an “external constraint” on the symmetry matrices, and can thus be seen as a post-processing of the unconstrained (full) PG of a structure.
== Input: ==
- Parameters
n_mat (integer) – number of matrices in the input mat_list
mat_list (np.ndarray((n_mat, 3, 3), dtype = float )) – list of 3x3 matrices of symmetry operations in input
b_field (3d vector, np.ndarray(3, dtype = float )) – direction of magnetic field
== output: ==
- Parameters
n_op (integer) – number of operations that fulfill the constraint of the desired magnetic field
matrix (np.ndarray( (n_op, 3, 3), dtype = float )) – the list of matrices that act on the system constrained by the desired magnetic field
- get_perm(nat, typ_in, coords, nm_in, mat_list)[source]
Description: Obtain the list of permutations and maximal distances for each matrix in input.
This is a wrapper to libira_get_perm() from library_sofi.f90
== Input: ==
- Parameters
nat (integer) – number of atoms in the structure
typ_in (np.ndarray( nat, dtype = integer or string )) – atomic types of the structure
coords (np.ndarray((nat, 3), dtype = float )) – atomic positions in the structure
nm_in (integer) – number of matrices in the mat_list input
mat_list (np.ndarray( (nm_in, 3, 3), dtype = float )) – list of input matrices
== Output: ==
- Parameters
perm (np.ndarray( (nm_in, nat), dtype = integer )) – list of permutations corresponding to each matrix operation in input
dHausdorff (np.ndarray( nm_in, dtype = float )) – maximal distance (Hausdorff distance) corresponding to the application off each matrix in the mat_list to the structure. Can be seen as “score” of each symmetry
- get_combos(nat, typ_in, coords, nm_in, mat_list)[source]
Description: Obtain all unique combinations of input matrices, which are symmetry operations of given structure.
This is a wrapper to the routine libira_get_combos() from library_sofi.f90
== Input: ==
- Parameters
nat (integer) – number of atoms in the structure
typ_in (np.ndarray( nat, dtype = integer or string )) – atomic types of the structure
coords (np.ndarray((nat, 3), dtype = float )) – atomic positions in the structure
nm_in (integer) – number of matrices in the mat_list input
mat_list (np.ndarray( (nm_in, 3, 3), dtype = float )) – list of input matrices
== Output: ==
- Parameters
nm_out (integer) – number of matrices in the output list mat_out
mat_out (np.ndarray( (nm_out, 3, 3), dtype = float )) – list of output matrices
- try_mat(nat, typ_in, coords, theta)[source]
Description: Apply a given matrix theta to the structure, and compute the distance between the transformed and original structure. If the distance is small, then theta is a symmetry operation (or close to). The distance is computed in a permutationally invariant way, using the CShDA algorithm, which imposes a one-to-one assignment of the atoms. The value of distance corresponds to the maximal value of distances between all assigned atomic pairs, which is the Hausdorff distance.
This is a wrapper to libira_try_mat() routine from library_sofi.f90
== Input: ==
- Parameters
nat (integer) – number of atoms in the structure
typ_in (np.ndarray( nat, dtype = integer or string )) – atomic types of the structure
coords (np.ndarray((nat, 3), dtype = float )) – atomic positions in the structure
theta (np.ndarray((3,3), dtype = float)) – the input matrix of an orthonormal operation to be tested on structure
== Output: ==
- Parameters
dh (float) – the Hausdorff distance value
perm (np.ndarray((nat), dtype = int )) – permutations of atoms which were assignmed by CShDA upon application of theta
- construct_operation(op, axis, angle)[source]
Description: Construct the 3x3 matrix corresponding to operation encoded by the Schoenflies Op, such that it acts along the desired axis, and given angle.
This is a wrapper to libira_construct_operation() routine from library_sofi.f90
== Input: ==
- Parameters
op (string) – Schoeflies Op name, possible values: - “E” = identity - “I” = inversion - “C” = rotation - “S” = (roto-)reflection
axis (3D vector, np.ndarray(3, dtype = float)) – the axis along which the desired operation should act
angle (float) – the angle by which the desired operation should rotate, in units of 1/(2pi), e.g. the value angle = 0.5 means half the circle, and angle = -1.0/6.0 means rotation about the axis in negative direction for 1/6th of the circle
== Output: ==
- Parameters
matrix (3x3 matrix, np.ndarray((3, 3), dtype = float )) – the matrix representation of desired operation
Note
The operation “E” is equivalent to “C” about any axis for angle=0.0; and similarly the operation “I” is equivalent to “S” with angle=0.5 about any axis. The operation “S” with angle=0.0 is a reflection.
- mat_combos(nm_in, mat_list)[source]
Description: Obtain all unique combinations of matrices in input, without checking them against any specific structure.
This is a wrapper to routine libira_mat_combos() from library_sofi.f90
== Input: ==
- Parameters
nm_in (integer) – number of matrices in the mat_list input
mat_list (np.ndarray( (nm_in, 3, 3), dtype = float )) – list of input matrices
== Output: ==
- Parameters
nm_out (integer) – number of matrices in the output list mat_out
mat_out (np.ndarray( (nm_out, 3, 3), dtype = float )) – list of output matrices
- matrix_distance(m1, m2)[source]
Compute the distance between two matrices using the
matrix_distance
function. This function is used internally in SOFI to determine if two matrices are equal or not, if the value of distance is belowm_thr
, then the matrices are considered equal. By default,m_thr = 0.73
which should be enough to distinguish matrices separated by operation equivalent to C 12^1. These values can be found in sofi_tools.f90== input ==
- Parameters
m1 (np.ndarray( [3, 3], dtype = float)) – matrix 1
m2 (np.ndarray( [3, 3], dtype = float)) – matrix 2
== output ==
- Parameters
d (float) – distance value
- check_collinear(nat, coords)[source]
Check if the input structure is collinear or not.
== input ==
- Parameters
nat (int) – number of atoms in the structure
coords (np.ndarray((nat,3), dtype=float)) – the atomic positions of the structure
== output ==
- Parameters
collinear (bool) – true if structure is collinear
ax (np.ndarray(3, dtype=float)) – axis of collinearity, if structure is collinear
- class ira_mod.sym_data[source]
Definition of the object, which is returned by ira_mod.SOFI.compute()
Members of the object:
- Parameters
n_sym (int) – number of symmetry elements found
matrix (np.ndarray((n_sym, 3, 3), dtype = float)) – the list of matrices of symmetry operations
perm (np.ndarray((n_sym, nat), dtype = int)) – the atomic permutation corresponding to application of that symmetry, start by index 0
op (np.ndarray((n_sym), type="U1"); size-1 strings) – Schoenflies notation: Op n^p; E=identity, I=inversion, C=rotation, S=(roto-)inversion
n (np.ndarray(n_sym, dtype = int )) – Schoenflies notation n
p (np.ndarray(n_sym, dtype = int )) – Schoenflies notation p
axis (np.ndarray((n_sym, 3), dtype = float )) – the axis over which a symmetry element operates (for S: normal vector to plane)
angle (np.ndarray(n_sym, dtype = float )) – angle of rotation of a symmetry element, in units of 1/2pi, e.g. angle=0.25 is 1/4 circle
dHausdorff (np.ndarray(n_sym, dtype = float )) – maximal displacement of any atom upon transformation by that symmetry matrix
pg (str) – point group of the structure
prin_ax (np.ndarray( 3, dtype = float )) – principal axis of the PG
- Function print
prints the full data of the sym_data object