Source code for mordred.Framework
from __future__ import division
import networkx as nx
from ._base import Descriptor
from .RingCount import Rings
__all__ = ("Framework",)
class FrameworkCache(Descriptor):
    __slots__ = ()
    def parameters(self):
        return ()
    def dependencies(self):
        return {"Rs": Rings()}
    def calculate(self, Rs):
        G = nx.Graph()
        Rd = {i: ("R", Ri) for Ri, R in enumerate(Rs) for i in R}
        R = list(set(Rd.values()))
        NR = len(R)
        for bond in self.mol.GetBonds():
            a = bond.GetBeginAtomIdx()
            b = bond.GetEndAtomIdx()
            a = Rd.get(a, ("A", a))
            b = Rd.get(b, ("A", b))
            G.add_edge(a, b)
        linkers = set()
        for Ri, Rj in ((i, j) for i in range(NR) for j in range(i + 1, NR)):
            Ra, Rb = R[Ri], R[Rj]
            try:
                linkers.update(i for t, i in nx.shortest_path(G, Ra, Rb) if t == "A")
            except nx.NetworkXNoPath:
                pass
        return linkers, Rs
[docs]class Framework(Descriptor):
    r"""molecular framework ratio descriptor.
    .. math::
        f_{\rm MF} = \frac{N_{\rm MF}}{N}
    where
    :math:`N_{\rm MF}` is number of atoms in molecular framework,
    :math:`N` is number of all atoms.
    References
        * :doi:`10.1021/jm9602928`
    """
    __slots__ = ()
[docs]    def description(self):
        return "molecular framework ratio" 
    @classmethod
    def preset(cls):
        yield cls()
    def __str__(self):
        return "fMF"
    def parameters(self):
        return ()
    def dependencies(self):
        return {"F": FrameworkCache()}
    def calculate(self, F):
        linkers, rings = F
        Nmf = len(linkers) + len({i for ring in rings for i in ring})
        N = self.mol.GetNumAtoms()
        return Nmf / N
    rtype = float