Source code for cgsmiles.linalg_functions
import numpy as np
from numpy import unravel_index
from scipy.spatial.distance import pdist, squareform
[docs]
def u_vect(vect):
"""
Compute unit vector of vector.
Parameters
----------
vect: :class:`numpy.ndarray`
Returns
-----------
:class:`numpy.ndarray`
"""
u_vect = vect/np.linalg.norm(vect)
return u_vect
[docs]
def vector_angle_degrees(v1, v2):
"""
Compute the angle between two vectors
in degrees and between 0 180 degrees.
Parameters
----------
v1: :class:`numpy.ndarray`
v2: :class:`numpy.ndarray`
Returns
---------
float
angle in degrees
"""
angle = np.degrees(np.arccos(np.clip(np.dot(u_vect(v1), u_vect(v2)),-1, 1)))
return angle
[docs]
def dihedral_angle_between(a1, a2, a3, a4):
"""
Compute dihedral angle between planes (a1, a2, a3) and (a2, a3, a4).
"""
r1 = a1 - a2
r2 = a3 - a2
r3 = a3 - a4
cross1 = np.cross(r1, r2)
cross2 = np.cross(r2, r3)
n1 = u_vect(cross1)
n2 = u_vect(cross2)
dih = vector_angle_degrees(n1, n2)
return dih
[docs]
def rotate(positions, angle, origin=np.array([0, 0])):
"""
Rotate positions by angle in 2D about the origin.
The angle is given in radians.
"""
positions = positions - origin
rotation_matrix = np.array([[np.cos(angle), -np.sin(angle)],
[np.sin(angle), np.cos(angle)]])
rotated_positions = np.dot(positions, rotation_matrix.T)
rotated_positions = rotated_positions + origin
return rotated_positions
[docs]
def rotate_degrees(position, angle, origin=np.array([0,0])):
"""
Wrapper for rotating about the origin but with angle
given in degrees.
"""
angle = np.deg2rad(angle)
return rotate(position, angle, origin)
[docs]
def rotate_to_axis(positions, align_with):
"""
Rotate position array to aling with one of the principle axis
or the diagonal.
"""
# get all the distances
distances = squareform(pdist(positions, 'euclidean'))
# find pair belonging to largest distance
pair = unravel_index(distances.argmax(), distances.shape)
# get vector
vector = positions[pair[0]] - positions[pair[1]]
angle = np.arctan2(align_with[1], align_with[0]) - np.arctan2(vector[1], vector[0])
rotated_positions = rotate(positions, angle)
return rotated_positions