Source code for BioSimSpace.Types._vector

######################################################################
# BioSimSpace: Making biomolecular simulation a breeze!
#
# Copyright: 2017-2024
#
# Authors: Lester Hedges <lester.hedges@gmail.com>
#
# BioSimSpace is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BioSimSpace is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BioSimSpace. If not, see <http://www.gnu.org/licenses/>.
#####################################################################

"""A general three-vector type."""

__author__ = "Lester Hedges"
__email__ = "lester.hedges@gmail.com"

__all__ = ["Vector"]

from sire.legacy.Maths import Vector as _Vector

from ._angle import Angle as _Angle


[docs] class Vector: """A three-vector."""
[docs] def __init__(self, x, y, z): """ Constructor. Parameters ---------- x : float The x component of the vector. y : float The y component of the vector. z : float The z component of the vector. """ try: x = float(x) except: raise TypeError("'x' must be of type 'float'") try: y = float(y) except: raise TypeError("'y' must be of type 'float'") try: z = float(z) except: raise TypeError("'z' must be of type 'float'") # Set the Sire Vector. self._sire_object = _Vector(x, y, z)
def __str__(self): """Return a human readable string representation of the object.""" return "(%s, %s, %s)" % (self.x(), self.y(), self.z()) def __repr__(self): """Return a human readable string representation of the object.""" return "(%s, %s, %s)" % (self.x(), self.y(), self.z()) def __pos__(self): """Unary + operator.""" return Vector(self.x(), self.y(), self.z()) def __neg__(self): """Unary - operator.""" return Vector(-self.x(), -self.y(), -self.z()) def __add__(self, other): """ Addition operator. Parameters ---------- other : :class: `Vector <BioSimSpace.Types.Vector>` Another vector. Return ------ result : :class: `Vector <BioSimSpace.Types.Vector>` The sum of the two vectors. """ if not isinstance(other, Vector): raise TypeError( "unsupported operand type(s) for +: '%s' and '%s'" % (self.__class__.__qualname__, other.__class__.__qualname__) ) return self._from_sire_vector(self._sire_object + other._sire_object) def __sub__(self, other): """ Subtraction operator. Parameters ---------- other : :class: `Vector <BioSimSpace.Types.Vector>` Another vector. Return ------ result : :class: `Vector <BioSimSpace.Types.Vector>` The difference of the two vectors. """ if not isinstance(other, Vector): raise TypeError( "unsupported operand type(s) for -: '%s' and '%s'" % (self.__class__.__qualname__, other.__class__.__qualname__) ) return self._from_sire_vector(self._sire_object - other._sire_object) def __mul__(self, other): """Multiplication operator.""" # Convert int to float. if type(other) is int: other = float(other) # Only support multiplication by float. if isinstance(other, float): # Return a new vector multiplied by other. return self._from_sire_vector(other * self._sire_object) else: raise TypeError( "unsupported operand type(s) for *: '%s' and '%s'" % (self.__class__.__qualname__, other.__class__.__qualname__) ) def __rmul__(self, other): """Multiplication operator.""" # Multiplication is commutative: a*b = b*a return self.__mul__(other) def __truediv__(self, other): """Division operator.""" # Convert int to float. if type(other) is int: other = float(other) # Float division. if isinstance(other, float): # Return a new vector divided by other. return self._from_sire_vector(self._sire_object / other) else: raise TypeError( "unsupported operand type(s) for /: '%s' and '%s'" % (self.__class__.__qualname__, other.__class__.__qualname__) )
[docs] def dot(self, other): """ Return the dot (scalar) product with the other vector. Parameters ---------- other : :class: `Vector <BioSimSpace.Types.Vector>` Another vector. Returns ------- result : float The scalar product. """ if not isinstance(other, Vector): raise TypeError("'other' must be of type 'BioSimSpace.Types.Vector'") return self._sire_object.dot(self._sire_object, other._sire_object)
[docs] def cross(self, other): """ Return the cross product with the other vector. Parameters ---------- other : :class: `Vector <BioSimSpace.Types.Vector>` Another vector. Returns ------- result : :class: `Vector <BioSimSpace.Types.Vector>` The cross product. """ if not isinstance(other, Vector): raise TypeError("'other' must be of type 'BioSimSpace.Types.Vector'") x = self.y() * other.z() - self.z() * other.y() y = self.z() * other.x() - self.x() * other.z() z = self.x() * other.y() - self.y() * other.x() # Create a new Vector using the x, y, z components. return Vector(x, y, z)
[docs] def angle(self, other): """ Return the angle between this and the other vector. Parameters ---------- other : :class: `Vector <BioSimSpace.Types.Vector>` Another vector. Returns ------- angle : :class: `Angle <BioSimSpace.Types.Angle>` The angle between the two vectors. """ if not isinstance(other, Vector): raise TypeError("'other' must be of type 'BioSimSpace.Types.Vector'") # Calculate the angle. angle = self._sire_object.angle(self._sire_object, other._sire_object) # Return as a BioSimSpace Angle type. return _Angle(angle.value(), "DEGREES").radians()
[docs] def x(self): """ Return the x component of the vector. Returns ------- x : float The x component of the vector. """ return self._sire_object.x().value()
[docs] def y(self): """ Return the y component of the vector. Returns ------- y : float The y component of the vector. """ return self._sire_object.y().value()
[docs] def z(self): """ Return the z component of the vector. Returns ------- z : float The z component of the vector. """ return self._sire_object.z().value()
[docs] def magnitude(self): """ Return the magnitude of the vector. Returns ------- length : float The magnitude of the vector. """ return self._sire_object.magnitude()
[docs] def normalise(self): """ Normalise the vector. Returns ------- vector : :class: `Vector <BioSimSpace.Types.Vector>` The normalised vector. """ return self._from_sire_vector(self._sire_object.normalise())
@staticmethod def _from_sire_vector(vector): """ Create a vector from a Sire.Maths.Vector object. Parameters ---------- vector : Sire.Maths.Vector The Sire Vector object. Returns ------- vector : :class: `Vector <BioSimSpace.Types.Vector>` A BioSimSpace Vector object. """ return Vector(vector.x().value(), vector.y().value(), vector.z().value())