diff --git a/propka/ligand.py b/propka/ligand.py index 618f105..88f389b 100644 --- a/propka/ligand.py +++ b/propka/ligand.py @@ -319,11 +319,11 @@ def are_atoms_planar(atoms): return False vec1 = Vector(atom1=atoms[0], atom2=atoms[1]) vec2 = Vector(atom1=atoms[0], atom2=atoms[2]) - norm = (vec1**vec2).rescale(1.0) + norm = vec1.cross(vec2).rescale(1.0) margin = PLANARITY_MARGIN for atom in atoms[3:]: vec = Vector(atom1=atoms[0], atom2=atom).rescale(1.0) - if abs(vec*norm) > margin: + if abs(vec.dot(norm)) > margin: return False return True diff --git a/propka/protonate.py b/propka/protonate.py index c32ada4..49a1f8d 100644 --- a/propka/protonate.py +++ b/propka/protonate.py @@ -274,15 +274,15 @@ class Protonate: vec2 = Vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0] .bonded_atoms[other_atom_indices[0]]) - axis = vec1**vec2 + axis = vec1.cross(vec2) # this is a trick to make sure that the order of atoms doesn't # influence the final postions of added protons if len(other_atom_indices) > 1: vec3 = Vector(atom1=atom.bonded_atoms[0], atom2=atom.bonded_atoms[0] .bonded_atoms[other_atom_indices[1]]) - axis2 = vec1**vec3 - if axis*axis2 > 0: + axis2 = vec1.cross(vec3) + if axis.dot(axis2) > 0: axis = axis+axis2 else: axis = axis-axis2 diff --git a/propka/vector_algebra.py b/propka/vector_algebra.py index d77aae4..b216037 100644 --- a/propka/vector_algebra.py +++ b/propka/vector_algebra.py @@ -7,6 +7,7 @@ Vector algebra for PROPKA. import logging import math from typing import Optional, Protocol, overload +import warnings _LOGGER = logging.getLogger(__name__) @@ -87,10 +88,11 @@ class Vector: def __mul__(self, other): """Dot product, scalar and matrix multiplication.""" if isinstance(other, Vector): - # TODO deprecate in favor of self.dot() + warnings.warn("Use Vector.dot() instead of operator.mul()", DeprecationWarning, stacklevel=2) return self.dot(other) if isinstance(other, Matrix4x4): - # TODO deprecate in favor of matmul operator + warnings.warn("Use M @ v (operator.matmul()) instead of M * v (operator.mul())", + DeprecationWarning, stacklevel=2) return other @ self if isinstance(other, (int, float)): return Vector(self.x * other, self.y * other, self.z * other) @@ -100,7 +102,7 @@ class Vector: return self.__mul__(other) def __pow__(self, other: _XYZ): - # TODO deprecate in favor of self.cross() + warnings.warn("Use Vector.cross() instead of operator.pow()", DeprecationWarning, stacklevel=2) return self.cross(other) def cross(self, other: _XYZ): @@ -195,7 +197,7 @@ def angle(avec: Vector, bvec: Vector) -> float: Returns: angle in radians """ - dot = avec * bvec + dot = avec.dot(bvec) return math.acos(dot / (avec.length() * bvec.length())) @@ -221,10 +223,10 @@ def signed_angle_around_axis(avec: Vector, bvec: Vector, axis: Vector) -> float: Returns: angle in radians """ - norma = avec**axis - normb = bvec**axis + norma = avec.cross(axis) + normb = bvec.cross(axis) ang = angle(norma, normb) - dot_ = bvec*(avec**axis) + dot_ = bvec.dot(avec.cross(axis)) if dot_ < 0: ang = -ang return ang @@ -248,21 +250,21 @@ def rotate_vector_around_an_axis(theta: float, axis: Vector, vec: Vector) -> Vec else: gamma = math.pi/2.0 rot_z = rotate_atoms_around_z_axis(gamma) - vec = rot_z * vec - axis = rot_z * axis + vec = rot_z @ vec + axis = rot_z @ axis beta = 0.0 if axis.x != 0: beta = -axis.x/abs(axis.x)*math.acos( axis.z/math.sqrt(axis.x*axis.x + axis.z*axis.z)) rot_y = rotate_atoms_around_y_axis(beta) - vec = rot_y * vec - axis = rot_y * axis + vec = rot_y @ vec + axis = rot_y @ axis rot_z = rotate_atoms_around_z_axis(theta) - vec = rot_z * vec + vec = rot_z @ vec rot_y = rotate_atoms_around_y_axis(-beta) - vec = rot_y * vec + vec = rot_y @ vec rot_z = rotate_atoms_around_z_axis(-gamma) - vec = rot_z * vec + vec = rot_z @ vec return vec diff --git a/tests/test_vector_algebra.py b/tests/test_vector_algebra.py index 0dd689f..0cde8f0 100644 --- a/tests/test_vector_algebra.py +++ b/tests/test_vector_algebra.py @@ -72,7 +72,8 @@ def test_Vector__mul__number(): def test_Vector__mul__Vector(): v1 = m.Vector(1, 2, 3) v2 = m.Vector(4, 5, 6) - assert v1 * v2 == 32 + with pytest.deprecated_call(): + assert v1 * v2 == 32 assert v1.dot(v2) == 32 with pytest.raises(TypeError): v1 @ v2 # type: ignore @@ -80,10 +81,12 @@ def test_Vector__mul__Vector(): def test_Vector__mul__Matrix4x4(): v1 = m.Vector(1, 2, 3) - assert_vector_equal(v1 * m.Matrix4x4(), m.Vector()) + assert_vector_equal(m.Matrix4x4() @ v1, m.Vector()) m2 = m.Matrix4x4(0, 1, 0, 0, 20, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 1) - assert_vector_equal(v1 * m2, m.Vector(2, 20, 900)) - assert_vector_equal(m2 * v1, m.Vector(2, 20, 900)) + with pytest.deprecated_call(): + assert_vector_equal(v1 * m2, m.Vector(2, 20, 900)) + with pytest.deprecated_call(): + assert_vector_equal(m2 * v1, m.Vector(2, 20, 900)) assert_vector_equal(m2 @ v1, m.Vector(2, 20, 900)) with pytest.raises(TypeError): v1 @ m2 # type: ignore @@ -92,7 +95,8 @@ def test_Vector__mul__Matrix4x4(): def test_Vector__cross(): v1 = m.Vector(1, 2, 3) v2 = m.Vector(4, 5, 6) - assert_vector_equal(v1**v2, m.Vector(-3, 6, -3)) # TODO deprecate + with pytest.deprecated_call(): + assert_vector_equal(v1**v2, m.Vector(-3, 6, -3)) assert_vector_equal(v1.cross(v2), m.Vector(-3, 6, -3)) assert_vector_equal(v2.cross(v1), m.Vector(3, -6, 3))