Source code for mordred.MomentOfInertia
import numpy as np
from ._base import Descriptor
from ._util import atoms_to_numpy
__all__ = ("MomentOfInertia",)
class MomentOfInertiaBase(Descriptor):
    __slots__ = ()
    require_3D = True
    def _numpy(self):
        ws = atoms_to_numpy(lambda a: a.GetMass(), self.mol)
        ps = self.coord - np.sum(ws[:, np.newaxis] * self.coord, axis=0) / np.sum(ws)
        return ws, ps
class PrincipalAxis(MomentOfInertiaBase):
    __slots__ = ()
    def parameters(self):
        return ()
    def calculate(self):
        ws, ps = self._numpy()
        I = np.sum(
            -ws[:, np.newaxis, np.newaxis] *
            (ps[:, np.newaxis] * ps[:, :, np.newaxis]),
            axis=0,
        )
        diag = np.sum(
            ws[:, np.newaxis] *
            (np.sum(ps ** 2, axis=1)[:, np.newaxis] - ps ** 2),
            axis=0,
        )
        np.fill_diagonal(I, diag)
        return np.sort(np.linalg.eig(I)[0])[::-1]
[docs]class MomentOfInertia(MomentOfInertiaBase):
    __slots__ = "_axis",
[docs]    def description(self):
        return "moment of inertia (axis = {})".format(self._axis) 
    @classmethod
    def preset(cls):
        return map(cls, cls.axes)
    def __str__(self):
        return "MOMI-{}".format(self._axis)
    def parameters(self):
        return self._axis,
    axes = ("X", "Y", "Z")
    _axis_to_index = {a: i for i, a in enumerate(axes)}
    def __init__(self, axis="X"):
        assert axis in self.axes
        self._axis = axis
    def dependencies(self):
        return {"I": PrincipalAxis()}
    def calculate(self, I):
        return I[self._axis_to_index[self._axis]]
    rtype = float