Source code for mordred.MolecularDistanceEdge

from six import string_types, integer_types
from numpy import product

from ._base import Descriptor
from ._graph_matrix import Valence, DistanceMatrix
from ._atomic_property import GetAtomicNumber, GetElementSymbol

__all__ = ("MolecularDistanceEdge",)


_sp_dict = {
    1: "primary",
    2: "secondary",
    3: "tertiary",
    4: "quaternary",
}


[docs]class MolecularDistanceEdge(Descriptor): r"""molecular distance edge descriptor. :type valence1: int :param valence1: valence of first atom :type valence2: int :param valence2: valence of second atom :type element: str or int :param element: atomic symbol or atomic number :returns: NaN when :math:`N_{\rm MDE} = 0` """ __slots__ = ("_valence1", "_valence2", "_atomic_num",) explicit_hydrogens = False
[docs] def description(self): return "molecular distance edge between {a} {e} and {b} {e}".format( a=_sp_dict[self._valence1], b=_sp_dict[self._valence2], e=GetElementSymbol(self._atomic_num), )
@classmethod def preset(cls): return ( cls(a, b, e) for e in [6, 8, 7] for a in range(1, 11 - e) for b in range(a, 11 - e) ) def __str__(self): return "MDE{}-{}{}".format( GetElementSymbol(self._atomic_num), self._valence1, self._valence2, ) def parameters(self): return self._valence1, self._valence2, GetElementSymbol(self._atomic_num) def __init__(self, valence1=1, valence2=1, element="C"): self._valence1 = min(valence1, valence2) self._valence2 = max(valence1, valence2) if isinstance(element, integer_types): self._atomic_num = element elif isinstance(element, string_types): self._atomic_num = GetAtomicNumber(element) else: raise ValueError("element must be atomic number or atomic symbol") def dependencies(self): return { "D": DistanceMatrix(self.explicit_hydrogens), "V": Valence(self.explicit_hydrogens), } def calculate(self, D, V): N = self.mol.GetNumAtoms() Dv = [ D[i, j] for i in range(N) for j in range(i + 1, N) if (V[i] == self._valence1 and V[j] == self._valence2) or (V[j] == self._valence1 and V[i] == self._valence2) if self.mol.GetAtomWithIdx(i).GetAtomicNum() == self.mol.GetAtomWithIdx(j).GetAtomicNum() == self._atomic_num ] n = len(Dv) with self.rethrow_zerodiv(): dx = product(Dv) ** (1. / (2. * n)) return n / (dx ** 2) rtype = float