From 95732b3119a89aa5648a2cae700dc544151cf09c Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Mon, 21 Aug 2017 17:27:10 +0900 Subject: [PATCH 1/8] change flake8-double-quotes to flake8-quotes --- scripts/requirements-flake8.txt | 2 +- setup.cfg | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/requirements-flake8.txt b/scripts/requirements-flake8.txt index 2e6a0c23..bd5c0081 100644 --- a/scripts/requirements-flake8.txt +++ b/scripts/requirements-flake8.txt @@ -1,6 +1,6 @@ pep8 flake8 -flake8-double-quotes +flake8-quotes flake8-print flake8-commas flake8-comprehensions diff --git a/setup.cfg b/setup.cfg index 90d44734..a8004f88 100644 --- a/setup.cfg +++ b/setup.cfg @@ -18,6 +18,7 @@ # H304 No relative imports. ignore = D100,D101,D102,D103,D105,D203,I101,N801,N802,N803,N806,N814,H301,H304,P101,P102,P103 max-line-length = 99 +inline-quotes = " [isort] line_length=100 From 183d67d2fc19f7cbd90adcf5e34f4b42bca61222 Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Tue, 22 Aug 2017 01:14:51 +0900 Subject: [PATCH 2/8] flake8 --- mordred/_base/result.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mordred/_base/result.py b/mordred/_base/result.py index 3314685b..3e1c8e18 100644 --- a/mordred/_base/result.py +++ b/mordred/_base/result.py @@ -8,8 +8,8 @@ def __init__(self, r, d): super(Result, self).__init__(r) self._descriptors = d - def fillna(self, value=float('nan')): - r"""Replace missing value to 'value'. + def fillna(self, value=float("nan")): + r"""Replace missing value to "value". Parameters: value: value that missing value is replaced From aecac3a829a11d9bc9c6df675263b52f72b9d43b Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Tue, 22 Aug 2017 01:16:36 +0900 Subject: [PATCH 3/8] add Descriptor.description method --- mordred/ABCIndex.py | 6 +++ mordred/AcidBase.py | 6 +++ mordred/AdjacencyMatrix.py | 3 ++ mordred/Aromatic.py | 6 +++ mordred/AtomCount.py | 12 ++++++ mordred/Autocorrelation.py | 16 ++++++++ mordred/BCUT.py | 8 ++++ mordred/BalabanJ.py | 3 ++ mordred/BaryszMatrix.py | 4 ++ mordred/BertzCT.py | 3 ++ mordred/BondCount.py | 22 +++++----- mordred/CPSA.py | 45 +++++++++++++++++++++ mordred/CarbonTypes.py | 10 +++++ mordred/Chi.py | 31 +++++++++++--- mordred/Constitutional.py | 6 +++ mordred/DetourMatrix.py | 6 +++ mordred/DistanceMatrix.py | 3 ++ mordred/EState.py | 12 ++++++ mordred/EccentricConnectivityIndex.py | 3 ++ mordred/ExtendedTopochemicalAtom.py | 58 +++++++++++++++++++++++++++ mordred/FragmentComplexity.py | 3 ++ mordred/Framework.py | 3 ++ mordred/GeometricalIndex.py | 12 ++++++ mordred/GravitationalIndex.py | 6 +++ mordred/HydrogenBond.py | 6 +++ mordred/InformationContent.py | 21 ++++++++++ mordred/KappaShapeIndex.py | 9 +++++ mordred/Lipinski.py | 6 +++ mordred/McGowanVolume.py | 3 ++ mordred/MoRSE.py | 6 +++ mordred/MoeType.py | 13 +++++- mordred/MolecularDistanceEdge.py | 17 +++++++- mordred/MolecularId.py | 15 +++++++ mordred/MomentOfInertia.py | 3 ++ mordred/PathCount.py | 12 +++++- mordred/Polarizability.py | 6 +++ mordred/RingCount.py | 14 +++++++ mordred/RotatableBond.py | 8 +++- mordred/SLogP.py | 6 +++ mordred/TopoPSA.py | 5 +++ mordred/TopologicalCharge.py | 8 +++- mordred/TopologicalIndex.py | 12 ++++++ mordred/VdwVolumeABC.py | 3 ++ mordred/VertexAdjacencyInformation.py | 3 ++ mordred/WalkCount.py | 7 ++++ mordred/Weight.py | 3 ++ mordred/WienerIndex.py | 5 +++ mordred/ZagrebIndex.py | 13 +++++- mordred/_base/descriptor.py | 3 ++ mordred/_matrix_attributes.py | 56 ++++++++++++++++++++++++++ mordred/_util.py | 11 +++++ 51 files changed, 537 insertions(+), 24 deletions(-) diff --git a/mordred/ABCIndex.py b/mordred/ABCIndex.py index cd224b6b..365abaee 100644 --- a/mordred/ABCIndex.py +++ b/mordred/ABCIndex.py @@ -41,6 +41,9 @@ class ABCIndex(ABCIndexBase): __slots__ = () + def description(self): + return "atom-bond connectivity index" + @staticmethod def _each_bond(bond): du = bond.GetBeginAtom().GetDegree() @@ -67,6 +70,9 @@ class ABCGGIndex(ABCIndexBase): __slots__ = () + def description(self): + return "Graovac-Ghorbani atom-bond connectivity index" + def dependencies(self): return {"D": DistanceMatrix(self.explicit_hydrogens)} diff --git a/mordred/AcidBase.py b/mordred/AcidBase.py index 7939a045..3d8e27f7 100644 --- a/mordred/AcidBase.py +++ b/mordred/AcidBase.py @@ -51,6 +51,9 @@ class AcidicGroupCount(SmartsCountBase): __slots__ = () + def description(self): + return "acidic group count" + _name = "nAcid" SMARTS = ( @@ -66,6 +69,9 @@ class BasicGroupCount(SmartsCountBase): __slots__ = () + def description(self): + return "basic group count" + _name = "nBase" SMARTS = ( diff --git a/mordred/AdjacencyMatrix.py b/mordred/AdjacencyMatrix.py index 745fd6b7..98e55947 100644 --- a/mordred/AdjacencyMatrix.py +++ b/mordred/AdjacencyMatrix.py @@ -15,6 +15,9 @@ class AdjacencyMatrix(Descriptor): __slots__ = ("_type",) explicit_hydrogens = False + def description(self): + return "{} of adjacency matrix".format(self._type.__name__) + @classmethod def preset(cls): return map(cls, methods) diff --git a/mordred/Aromatic.py b/mordred/Aromatic.py index ed692216..2fcb3cec 100644 --- a/mordred/Aromatic.py +++ b/mordred/Aromatic.py @@ -27,6 +27,9 @@ class AromaticAtomsCount(AromaticBase): __slots__ = () _name = "nAromAtom" + def description(self): + return "aromatic atoms count" + def calculate(self): return sum( 1 @@ -41,6 +44,9 @@ class AromaticBondsCount(AromaticBase): __slots__ = () _name = "nAromBond" + def description(self): + return "aromatic bonds count" + def calculate(self): return sum( 1 diff --git a/mordred/AtomCount.py b/mordred/AtomCount.py index 43593926..a94d7e1e 100644 --- a/mordred/AtomCount.py +++ b/mordred/AtomCount.py @@ -8,6 +8,15 @@ ) +_desc_conv = { + "Atom": "all", + "Bridgehead": "bridgehead", + "HeavyAtom": "heavy", + "Spiro": "spiro", + "X": "halogen", +} + + class AtomCount(Descriptor): r"""atom count descriptor. @@ -24,6 +33,9 @@ class AtomCount(Descriptor): __slots__ = ("_type",) + def description(self): + return "number of {} atoms".format(_desc_conv.get(self._type, self._type)) + @classmethod def preset(cls): return map(cls, [ diff --git a/mordred/Autocorrelation.py b/mordred/Autocorrelation.py index df89a33d..075965e9 100644 --- a/mordred/Autocorrelation.py +++ b/mordred/Autocorrelation.py @@ -18,6 +18,10 @@ def __str__(self): self._avec.as_argument, ) + def description(self): + return "{} of lag {} weighted by {}".format( + self._description_name, self._order, self._avec.get_long()) + def parameters(self): return self._order, self._prop @@ -155,6 +159,8 @@ class ATS(AutocorrelationBase): __slots__ = () + _description_name = "moreau-broto autocorrelation" + @classmethod def preset(cls): return ( @@ -193,6 +199,8 @@ class AATS(ATS): __slots__ = () + _description_name = "averaged moreau-broto autocorrelation" + def dependencies(self): return {"ATS": self._ATS, "gsum": self._gsum} @@ -216,6 +224,8 @@ class ATSC(AutocorrelationBase): __slots__ = () + _description_name = "centered moreau-broto autocorrelation" + @classmethod def preset(cls): return ( @@ -254,6 +264,8 @@ class AATSC(ATSC): __slots__ = () + _description_name = "averaged and centered moreau-broto autocorrelation" + def dependencies(self): return {"ATSC": self._ATSC, "gsum": self._gsum} @@ -283,6 +295,8 @@ class MATS(AutocorrelationBase): __slots__ = () + _description_name = "moran coefficient" + @classmethod def preset(cls): return ( @@ -317,6 +331,8 @@ class GATS(MATS): __slots__ = () + _description_name = "geary coefficient" + def dependencies(self): return { "avec": self._avec, diff --git a/mordred/BCUT.py b/mordred/BCUT.py index 1dea0f97..12956c3e 100644 --- a/mordred/BCUT.py +++ b/mordred/BCUT.py @@ -1,6 +1,7 @@ import numpy as np from ._base import Descriptor +from ._util import to_ordinal from ._atomic_property import AtomicProperty, get_properties __all__ = ("BCUT",) @@ -87,6 +88,13 @@ class BCUT(BCUTBase): __slots__ = ("_prop", "_nth",) + def description(self): + return "{} {} eigenvalue of Burden matrix weighted by {}".format( + to_ordinal(np.abs(self._nth) if self._nth < 0 else 1 + self._nth), + "lowest" if self._nth < 0 else "heighest", + self._prop.get_long(), + ) + @classmethod def preset(cls): return ( diff --git a/mordred/BalabanJ.py b/mordred/BalabanJ.py index b3dac42f..ff5ce8d5 100644 --- a/mordred/BalabanJ.py +++ b/mordred/BalabanJ.py @@ -11,6 +11,9 @@ class BalabanJ(Descriptor): __slots__ = () + def description(self): + return "Balaban's J index" + explicit_hydrogens = False @classmethod diff --git a/mordred/BaryszMatrix.py b/mordred/BaryszMatrix.py index c6c9290e..78bf1454 100644 --- a/mordred/BaryszMatrix.py +++ b/mordred/BaryszMatrix.py @@ -64,6 +64,10 @@ class BaryszMatrix(BaryszMatrixBase): __slots__ = ("_prop", "_type",) + def description(self): + return "{} from Barysz matrix weighted by {}".format( + self._type.description(), self._prop.get_long()) + @classmethod def preset(cls): return (cls(p, m) for p in get_properties() for m in methods) diff --git a/mordred/BertzCT.py b/mordred/BertzCT.py index aafcd308..c9338908 100644 --- a/mordred/BertzCT.py +++ b/mordred/BertzCT.py @@ -12,6 +12,9 @@ class BertzCT(Descriptor): __slots__ = () explicit_hydrogens = False + def description(self): + return "Bertz CT" + @classmethod def preset(cls): yield cls() diff --git a/mordred/BondCount.py b/mordred/BondCount.py index fe6a4548..4190e9d1 100644 --- a/mordred/BondCount.py +++ b/mordred/BondCount.py @@ -28,16 +28,16 @@ def as_argument(self): bond_types = ( - (BondType.any, ("", lambda _: True)), - (BondType.heavy, ("O", lambda _: True)), + (BondType.any, ("", "all bonds", lambda _: True)), + (BondType.heavy, ("O", "bonds connecting to heavy atom", lambda _: True)), - (BondType.single, ("S", lambda b: b.GetBondType() == Chem.BondType.SINGLE)), - (BondType.double, ("D", lambda b: b.GetBondType() == Chem.BondType.DOUBLE)), - (BondType.triple, ("T", lambda b: b.GetBondType() == Chem.BondType.TRIPLE)), + (BondType.single, ("S", "single bonds", lambda b: b.GetBondType() == Chem.BondType.SINGLE)), + (BondType.double, ("D", "double bonds", lambda b: b.GetBondType() == Chem.BondType.DOUBLE)), + (BondType.triple, ("T", "triple bonds", lambda b: b.GetBondType() == Chem.BondType.TRIPLE)), - (BondType.aromatic, ("A", lambda b: b.GetIsAromatic() or + (BondType.aromatic, ("A", "aromatic bonds", lambda b: b.GetIsAromatic() or b.GetBondType() == Chem.BondType.AROMATIC)), - (BondType.multiple, ("M", lambda b: b.GetIsAromatic() or + (BondType.multiple, ("M", "multiple bonds", lambda b: b.GetIsAromatic() or b.GetBondType() != Chem.BondType.SINGLE)), ) @@ -54,7 +54,11 @@ class BondCount(Descriptor): :param kekulize: use kekulized structure """ - __slots__ = ("_type", "_bond_name", "_check_bond", "kekulize",) + __slots__ = ("_type", "_bond_name", "_bond_desc", "_check_bond", "kekulize",) + + def description(self): + return "number of {} in {}kekulized structure".format( + self._bond_desc, "" if self.kekulize else "non-") bond_types = tuple(b.name for b in BondType) @@ -80,7 +84,7 @@ def parameters(self): def __init__(self, type="any", kekulize=False): self._type = parse_enum(BondType, type) - self._bond_name, self._check_bond = bond_type_dict[self._type] + self._bond_name, self._bond_desc, self._check_bond = bond_type_dict[self._type] self.kekulize = kekulize def calculate(self): diff --git a/mordred/CPSA.py b/mordred/CPSA.py index 0d34c64e..4f1df417 100644 --- a/mordred/CPSA.py +++ b/mordred/CPSA.py @@ -118,6 +118,9 @@ class PNSA(VersionCPSABase): __slots__ = () + def description(self): + return "partial negative surface area (version {})".format(self._version) + def dependencies(self): return { "SA": AtomicSurfaceArea(), @@ -155,6 +158,9 @@ class PPSA(PNSA): __slots__ = () + def description(self): + return "partial positive surface area (version {})".format(self._version) + @staticmethod def _mask(charges): return charges > 0.0 @@ -169,6 +175,9 @@ class DPSA(VersionCPSABase): __slots__ = () + def description(self): + return "difference in charged partial surface area (version {})".format(self._version) + def dependencies(self): return { "PNSA": PNSA(self._version), @@ -188,6 +197,9 @@ class FNSA(VersionCPSABase): __slots__ = () + def description(self): + return "fractional charged partial negative surface area (version {})".format(self._version) # noqa: E501 + def _SA(self): return PNSA(self._version) @@ -210,6 +222,9 @@ class FPSA(FNSA): __slots__ = () + def description(self): + return "fractional charged partial positive surface area (version {})".format(self._version) # noqa: E501 + def _SA(self): return PPSA(self._version) @@ -223,6 +238,9 @@ class WNSA(FNSA): __slots__ = () + def description(self): + return "surface weighted charged partial negative surface area (version {})".format(self._version) # noqa: E501 + def calculate(self, SA, ASA): return SA * np.sum(ASA) / 1000.0 @@ -236,6 +254,9 @@ class WPSA(FPSA): __slots__ = () + def description(self): + return "surface weighted charged partial positive surface area (version {})".format(self._version) # noqa: E501 + def calculate(self, SA, ASA): return SA * np.sum(ASA) / 1000.0 @@ -246,6 +267,9 @@ class RNCG(CPSABase): __slots__ = () require_3D = False + def description(self): + return "relative negative charge" + @staticmethod def _mask(charges): return charges < 0.0 @@ -268,6 +292,9 @@ class RPCG(RNCG): __slots__ = () + def description(self): + return "relative positive charge" + @staticmethod def _mask(charges): return charges > 0.0 @@ -279,6 +306,9 @@ class RNCS(CPSABase): __slots__ = () _RCG = RNCG() + def description(self): + return "relative negative charge surface area" + def dependencies(self): return { "RCG": self._RCG, @@ -308,6 +338,9 @@ class RPCS(RNCS): __slots__ = () + def description(self): + return "relative positive charge surface area" + @staticmethod def _mask(charges): return charges > 0 @@ -320,6 +353,9 @@ class TASA(CPSABase): __slots__ = () + def description(self): + return "total hydrophobic surface area" + @staticmethod def _mask(charges): return np.abs(charges) < 0.2 @@ -339,6 +375,9 @@ class TPSA(TASA): __slots__ = () + def description(self): + return "total polar surface area" + @staticmethod def _mask(charges): return np.abs(charges) >= 0.2 @@ -350,6 +389,9 @@ class RASA(CPSABase): __slots__ = () _TxSA = TASA() + def description(self): + return "relative hydrophobic surface area" + def dependencies(self): return { "SASA": AtomicSurfaceArea(), @@ -363,5 +405,8 @@ def calculate(self, TxSA, SASA): class RPSA(RASA): r"""relative polar surface area descriptor.""" + def description(self): + return "relative polar surface area" + __slots__ = () _TxSA = TPSA() diff --git a/mordred/CarbonTypes.py b/mordred/CarbonTypes.py index 6795a186..b843a7d1 100644 --- a/mordred/CarbonTypes.py +++ b/mordred/CarbonTypes.py @@ -61,6 +61,13 @@ class CarbonTypes(CarbonTypesBase): __slots__ = ("_nCarbon", "_SP",) + def description(self): + return "SP{} carbon bound to {} other carbon{}".format( + self._SP if self._SP != 1 else "", + self._nCarbon, + "s" if self._nCarbon > 1 else "", + ) + @classmethod def preset(cls): return map(lambda args: cls(*args), [ @@ -100,6 +107,9 @@ class HybridizationRatio(CarbonTypesBase): :returns: NaN when :math:`N_{\rm SP2} + N_{\rm SP3} = 0`. """ + def description(self): + return "hybridization ratio" + __slots__ = () @classmethod diff --git a/mordred/Chi.py b/mordred/Chi.py index 3acdd1e6..96d0e5fc 100644 --- a/mordred/Chi.py +++ b/mordred/Chi.py @@ -25,14 +25,25 @@ def as_argument(self): @property def short(self): - _chi_type_dict = { - self.__class__.path: "p", - self.__class__.chain: "ch", - self.__class__.path_cluster: "pc", - self.__class__.cluster: "c", + _short_dict = { + self.path: "p", + self.chain: "ch", + self.path_cluster: "pc", + self.cluster: "c", } - return _chi_type_dict[self] + return _short_dict[self] + + @property + def long(self): + _long_dict = { + self.path: "Chi path", + self.chain: "Chi chain", + self.path_cluster: "Chi path-cluster", + self.cluster: "Chi cluster", + } + + return _long_dict[self] class DFS(object): @@ -167,6 +178,14 @@ class Chi(ChiBase): _deltas = ["d", "dv"] + def description(self): + return "{}-ordered {}{} weighted by {}".format( + self._order, + "averaged " if self._averaged else "", + self._type.long, + self._prop.get_long(), + ) + @classmethod def preset(cls): return chain( diff --git a/mordred/Constitutional.py b/mordred/Constitutional.py index 29490ec4..2128a445 100644 --- a/mordred/Constitutional.py +++ b/mordred/Constitutional.py @@ -22,6 +22,9 @@ class ConstitutionalSum(Descriptor): __slots__ = ("_prop",) + def description(self): + return "sum of constitutional weighted by {}".format(self._prop.get_long()) + @classmethod def preset(cls): return map(cls, get_properties()) @@ -61,6 +64,9 @@ class ConstitutionalMean(ConstitutionalSum): __slots__ = ("_prop",) _prefix = "M" + def description(self): + return "mean of constitutional weighted by {}".format(self._prop.get_long()) + @classmethod def preset(cls): return map(cls, get_properties()) diff --git a/mordred/DetourMatrix.py b/mordred/DetourMatrix.py index 890d0d3f..f58e65fa 100644 --- a/mordred/DetourMatrix.py +++ b/mordred/DetourMatrix.py @@ -156,6 +156,9 @@ class DetourMatrix(DetourMatrixBase): __slots__ = ("_type",) + def description(self): + return "{} from detourn matrix".format(self._type.description()) + @classmethod def preset(cls): return map(cls, ma.methods) @@ -198,6 +201,9 @@ class DetourIndex(DetourMatrixBase): __slots__ = () + def description(self): + return "detour index" + def parameters(self): return () diff --git a/mordred/DistanceMatrix.py b/mordred/DistanceMatrix.py index 7d0c89c8..2f54dcef 100644 --- a/mordred/DistanceMatrix.py +++ b/mordred/DistanceMatrix.py @@ -15,6 +15,9 @@ class DistanceMatrix(Descriptor): __slots__ = ("_type",) explicit_hydrogens = False + def description(self): + return "{} from distance matrix".format(self._type.description()) + @classmethod def preset(cls): return map(cls, methods) diff --git a/mordred/EState.py b/mordred/EState.py index 2daffc0b..fcdb5095 100644 --- a/mordred/EState.py +++ b/mordred/EState.py @@ -57,6 +57,15 @@ class AggrType(IntEnum): def as_argument(self): return self.name + def description(self): + d = { + self.count: "number", + self.sum: "sum", + self.max: "max", + self.min: "min", + } + return d[self] + aggr_names = ( (AggrType.count, "N"), @@ -87,6 +96,9 @@ class AtomTypeEState(EStateBase): __slots__ = ("_type", "_estate",) + def description(self): + return "{} of {}".format(self._type.description(), self._estate) + aggr_types = tuple(a.name for a in AggrType) es_types = es_types diff --git a/mordred/EccentricConnectivityIndex.py b/mordred/EccentricConnectivityIndex.py index 6f10ae30..16923415 100644 --- a/mordred/EccentricConnectivityIndex.py +++ b/mordred/EccentricConnectivityIndex.py @@ -18,6 +18,9 @@ class EccentricConnectivityIndex(Descriptor): __slots__ = () explicit_hydrogens = False + def description(self): + return "eccentric connectivity index" + @classmethod def preset(cls): yield cls() diff --git a/mordred/ExtendedTopochemicalAtom.py b/mordred/ExtendedTopochemicalAtom.py index f1afd59e..d68a81bc 100644 --- a/mordred/ExtendedTopochemicalAtom.py +++ b/mordred/ExtendedTopochemicalAtom.py @@ -126,6 +126,12 @@ class EtaCoreCount(EtaBase): __slots__ = ("_averaged", "_reference",) + def description(self): + return "{}ETA core count{}".format( + "averaged " if self._averaged else "", + " for reference graph" if self._reference else "", + ) + @classmethod def preset(cls): return map(cls, [False, True]) @@ -172,6 +178,9 @@ class EtaShapeIndex(EtaBase): __slots__ = ("_type",) + def description(self): + return "ETA shape index (type: {})".format(self._type) + shape_types = ("p", "y", "x",) _type_to_degree = {"p": 1, "y": 3, "x": 4} @@ -251,6 +260,18 @@ class EtaVEMCount(EtaBase): __slots__ = ("_type", "_averaged",) + def description(self): + if self._type == "": + d = "" + elif self._type == "s": + d = "sigma contribution to " + elif self._type == "ns": + d = "nonsigma contribution to " + else: + d = "delta contribution to " + + return "{}{}valence electron mobile count".format("averaged " if self._averaged else "", d) + @classmethod def preset(cls): return ( @@ -330,6 +351,13 @@ class EtaCompositeIndex(EtaBase): __slots__ = ("_reference", "_local", "_averaged",) + def description(self): + return "{}{}ETA composite index{}".format( + "averaged " if self._averaged else "", + "local " if self._local else "", + " for reference graph", + ) + @classmethod def preset(cls): ft = [False, True] @@ -412,6 +440,12 @@ class EtaFunctionalityIndex(EtaBase): __slots__ = ("_local", "_averaged",) + def description(self): + return "{}{}ETA functionality index".format( + "averaged " if self._averaged else "", + "local " if self._local else "", + ) + @classmethod def preset(cls): return ( @@ -467,6 +501,12 @@ class EtaBranchingIndex(EtaBase): __slots__ = ("_ring", "_averaged",) + def description(self): + return "{}ETA branching index{}".format( + "averaged " if self._averaged else "", + " (use ring count)" if self._ring else "", + ) + @classmethod def preset(cls): return ( @@ -526,6 +566,9 @@ class EtaDeltaAlpha(EtaBase): __slots__ = ("_type",) + def description(self): + return "ETA delta alpha (type: {})".format(self._type) + delta_types = ("A", "B",) @classmethod @@ -585,6 +628,9 @@ class EtaEpsilon(EtaBase): __slots__ = ("_type",) + def description(self): + return "ETA epsilon (type: {})".format(self._type) + @classmethod def preset(cls): return map(cls, cls.epsilon_types) @@ -642,6 +688,9 @@ class EtaDeltaEpsilon(EtaBase): __slots__ = ("_type",) + def description(self): + return "ETA delta epsilon (type: {})".format(self._type) + @classmethod def preset(cls): return map(cls, cls.delta_epsilon_types) @@ -687,6 +736,9 @@ class EtaDeltaBeta(EtaBase): __slots__ = ("_averaged",) + def description(self): + return "{}ETA delta beta".format("averaged " if self._averaged else "") + @classmethod def preset(cls): return (cls(a) for a in [False, True]) @@ -724,6 +776,9 @@ class EtaPsi(EtaBase): \psi_1 = \frac{\alpha}{A \cdot \epsilon^2} """ + def description(self): + return "ETA psi" + @classmethod def preset(cls): yield cls() @@ -758,6 +813,9 @@ class EtaDeltaPsi(EtaBase): __slots__ = ("_type",) + def description(self): + return "ETA delta psi (type: {})".format(self._type) + @classmethod def preset(cls): return map(cls, cls.delta_psi_types) diff --git a/mordred/FragmentComplexity.py b/mordred/FragmentComplexity.py index 8f67895b..7437dbde 100644 --- a/mordred/FragmentComplexity.py +++ b/mordred/FragmentComplexity.py @@ -23,6 +23,9 @@ class FragmentComplexity(Descriptor): __slots__ = () + def description(self): + return "fragment complexity" + @classmethod def preset(cls): yield cls() diff --git a/mordred/Framework.py b/mordred/Framework.py index cc981463..c9aaad9a 100644 --- a/mordred/Framework.py +++ b/mordred/Framework.py @@ -61,6 +61,9 @@ class Framework(Descriptor): __slots__ = () + def description(self): + return "molecular framework ratio" + @classmethod def preset(cls): yield cls() diff --git a/mordred/GeometricalIndex.py b/mordred/GeometricalIndex.py index 26203d64..228ea2f8 100644 --- a/mordred/GeometricalIndex.py +++ b/mordred/GeometricalIndex.py @@ -27,6 +27,9 @@ class Radius3D(GeometricalIndexBase): __slots__ = () + def description(self): + return "geometric radius" + def __str__(self): return "GeomRadius" @@ -42,6 +45,9 @@ class Diameter3D(GeometricalIndexBase): __slots__ = () + def description(self): + return "geometric diameter" + def __str__(self): return "GeomDiameter" @@ -68,6 +74,9 @@ class GeometricalShapeIndex(GeometricalIndexBase): __slots__ = () + def description(self): + return "geometrical shape index" + def __str__(self): return "GeomShapeIndex" @@ -98,6 +107,9 @@ class PetitjeanIndex3D(GeometricalShapeIndex): __slots__ = () + def description(self): + return "geometric Petitjean index" + def __str__(self): return "GeomPetitjeanIndex" diff --git a/mordred/GravitationalIndex.py b/mordred/GravitationalIndex.py index 882bf547..cb7da2b0 100644 --- a/mordred/GravitationalIndex.py +++ b/mordred/GravitationalIndex.py @@ -10,6 +10,12 @@ class GravitationalIndex(Descriptor): __slots__ = "_heavy", "_pair" + def description(self): + return "{}{}gravitational index".format( + "heavy atom " if self._heavy else "", + "pair " if self._pair else "", + ) + @classmethod def preset(cls): return ( diff --git a/mordred/HydrogenBond.py b/mordred/HydrogenBond.py index ee63f724..68b29e63 100644 --- a/mordred/HydrogenBond.py +++ b/mordred/HydrogenBond.py @@ -23,6 +23,9 @@ class HBondAcceptor(HBondBase): __slots__ = () + def description(self): + return "number of hydrogen bond acceptor" + def __str__(self): return "nHBAcc" @@ -38,6 +41,9 @@ class HBondDonor(HBondBase): __slots__ = () + def description(self): + return "number of hydrogen bond donor" + def __str__(self): return "nHBDon" diff --git a/mordred/InformationContent.py b/mordred/InformationContent.py index 959e5967..02865ef8 100644 --- a/mordred/InformationContent.py +++ b/mordred/InformationContent.py @@ -155,6 +155,9 @@ class InformationContent(InformationContentBase): __slots__ = () + def description(self): + return "{}-ordered neighborhood information content".format(self._order) + _name = "IC" def dependencies(self): @@ -177,6 +180,9 @@ class TotalIC(InformationContentBase): __slots__ = () + def description(self): + return "{}-ordered neighborhood total information content".format(self._order) + _name = "TIC" def dependencies(self): @@ -200,6 +206,9 @@ class StructuralIC(TotalIC): __slots__ = () + def description(self): + return "{}-ordered structural information content".format(self._order) + _name = "SIC" def calculate(self, ICm): @@ -223,6 +232,9 @@ class BondingIC(TotalIC): __slots__ = () + def description(self): + return "{}-ordered bonding information content".format(self._order) + _name = "BIC" def calculate(self, ICm): @@ -245,6 +257,9 @@ class ComplementaryIC(TotalIC): __slots__ = () + def description(self): + return "{}-ordered complementary information content".format(self._order) + _name = "CIC" def calculate(self, ICm): @@ -262,6 +277,9 @@ class ModifiedIC(InformationContent): __slots__ = () + def description(self): + return "{}-ordered modified information content".format(self._order) + _name = "MIC" def calculate(self, iAgs): @@ -279,6 +297,9 @@ class ZModifiedIC(InformationContent): __slots__ = () + def description(self): + return "{}-ordered Z-modified information content".format(self._order) + _name = "ZMIC" def calculate(self, iAgs): diff --git a/mordred/KappaShapeIndex.py b/mordred/KappaShapeIndex.py index 2c1ed298..57ece734 100644 --- a/mordred/KappaShapeIndex.py +++ b/mordred/KappaShapeIndex.py @@ -44,6 +44,9 @@ class KappaShapeIndex1(KappaShapeIndexBase): __slots__ = () + def description(self): + return "kappa shape index 1" + def calculate(self, Chi): P, A, Pmin = self._common(Chi) Pmax = 0.5 * A * (A - 1) @@ -60,6 +63,9 @@ class KappaShapeIndex2(KappaShapeIndexBase): __slots__ = () + def description(self): + return "kappa shape index 2" + def calculate(self, Chi): P, A, Pmin = self._common(Chi) Pmax = 0.5 * (A - 1) * (A - 2) @@ -76,6 +82,9 @@ class KappaShapeIndex3(KappaShapeIndexBase): __slots__ = () + def description(self): + return "kappa shape index 3" + def calculate(self, Chi): P, A, Pmin = self._common(Chi) diff --git a/mordred/Lipinski.py b/mordred/Lipinski.py index 74aa1825..54189142 100644 --- a/mordred/Lipinski.py +++ b/mordred/Lipinski.py @@ -30,6 +30,9 @@ class Lipinski(LipinskiLike): __slots__ = () + def description(self): + return "Lipinski rule of five" + def dependencies(self): return { "HBAcc": HBondAcceptor(), @@ -54,6 +57,9 @@ class GhoseFilter(LipinskiLike): __slots__ = () + def description(self): + return "Ghose filter" + def dependencies(self): return { "LogP": SLogP(), diff --git a/mordred/McGowanVolume.py b/mordred/McGowanVolume.py index 9730ca3d..5eba4f8b 100644 --- a/mordred/McGowanVolume.py +++ b/mordred/McGowanVolume.py @@ -16,6 +16,9 @@ class McGowanVolume(Descriptor): __slots__ = () + def description(self): + return "McGowan volume" + @classmethod def preset(cls): yield cls() diff --git a/mordred/MoRSE.py b/mordred/MoRSE.py index 120c2baf..aa46e01e 100644 --- a/mordred/MoRSE.py +++ b/mordred/MoRSE.py @@ -16,6 +16,12 @@ class MoRSE(Descriptor): require_3D = True + def description(self): + return "3D-MoRSE{} (distance = {})".format( + "" if self._prop is None else " weighted by {}".format(self._prop.get_long()), + self._distance, + ) + @classmethod def preset(cls): return chain( diff --git a/mordred/MoeType.py b/mordred/MoeType.py index 985699ef..750c8032 100644 --- a/mordred/MoeType.py +++ b/mordred/MoeType.py @@ -16,6 +16,9 @@ class LabuteASA(Descriptor): __slots__ = () explicit_hydrogens = False + def description(self): + return "Labute's Approximate Surface Area" + @classmethod def preset(cls): yield cls() @@ -41,6 +44,13 @@ class MoeTypeBase(Descriptor): def preset(cls): return map(cls, range(1, cls.k_max)) + def description(self): + return self._fn.__doc__ + + @property + def _fn(self): + return getattr(self._module, str(self)) + def __str__(self): return self.__class__.__name__ + str(self._k) @@ -52,8 +62,7 @@ def __init__(self, k=1): self._k = k def calculate(self): - f = getattr(self._module, str(self)) - return f(self.mol) + return self._fn(self.mol) rtype = float diff --git a/mordred/MolecularDistanceEdge.py b/mordred/MolecularDistanceEdge.py index 86a270f6..0854a168 100644 --- a/mordred/MolecularDistanceEdge.py +++ b/mordred/MolecularDistanceEdge.py @@ -8,6 +8,14 @@ __all__ = ("MolecularDistanceEdge",) +_sp_dict = { + 1: "primary", + 2: "secondary", + 3: "tertiary", + 4: "quaternary", +} + + class MolecularDistanceEdge(Descriptor): r"""molecular distance edge descriptor. @@ -26,6 +34,13 @@ class MolecularDistanceEdge(Descriptor): __slots__ = ("_valence1", "_valence2", "_atomic_num",) explicit_hydrogens = False + 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=table.GetElementSymbol(self._atomic_num), + ) + @classmethod def preset(cls): return ( @@ -43,7 +58,7 @@ def __str__(self): ) def parameters(self): - return self._valence1, self._valence2, self._atomic_num + return self._valence1, self._valence2, table.GetElementSymbol(self._atomic_num) def __init__(self, valence1=1, valence2=1, element="C"): self._valence1 = min(valence1, valence2) diff --git a/mordred/MolecularId.py b/mordred/MolecularId.py index 6d1548a7..c1684e3e 100644 --- a/mordred/MolecularId.py +++ b/mordred/MolecularId.py @@ -1,5 +1,6 @@ import math +from six import integer_types from networkx import Graph from ._base import Descriptor @@ -103,6 +104,20 @@ class MolecularId(MolecularIdBase): __slots__ = ("_orig_type", "_averaged", "_eps", "_type", "_check") + def description(self): + if self._type == "any": + t = "" + elif self._type == "X": + t = " on halogen atoms" + else: + e = self._type + if isinstance(e, integer_types): + e = table.GetAtomicSymbol(e) + + t = " on {} atoms".format(e) + + return "{}molecular ID{}".format("averaged " if self._averaged else "", t) + @classmethod def preset(cls): return ( diff --git a/mordred/MomentOfInertia.py b/mordred/MomentOfInertia.py index 3e5dd7d6..fa974193 100644 --- a/mordred/MomentOfInertia.py +++ b/mordred/MomentOfInertia.py @@ -45,6 +45,9 @@ def calculate(self): class MomentOfInertia(MomentOfInertiaBase): __slots__ = "_axis", + def description(self): + return "moment of inertia (axis = {})".format(self._axis) + @classmethod def preset(cls): return map(cls, cls.axes) diff --git a/mordred/PathCount.py b/mordred/PathCount.py index e022cbfa..8af5a452 100644 --- a/mordred/PathCount.py +++ b/mordred/PathCount.py @@ -108,6 +108,16 @@ class PathCount(PathCountBase): :param log: use log scale """ + __slots__ = ("_order", "_pi", "_total", "_log",) + + def description(self): + return "{}-ordered {}{}path count{}".format( + self._order, + "total " if self._total else "", + "pi-" if self._pi else "", + " (log scale)" if self._log else "", + ) + @classmethod def preset(cls): return chain( @@ -123,8 +133,6 @@ def __str__(self): return "{}{}{}".format(base, pi, self._order) - __slots__ = ("_order", "_pi", "_total", "_log",) - def parameters(self): return self._order, self._pi, self._total, self._log diff --git a/mordred/Polarizability.py b/mordred/Polarizability.py index ce15405e..55224597 100644 --- a/mordred/Polarizability.py +++ b/mordred/Polarizability.py @@ -35,6 +35,9 @@ class APol(PolarizabilityBase): __slots__ = () + def description(self): + return "atomic polarizability" + def calculate(self): table = self._get_table() return sum(table[a.GetAtomicNum()] for a in self.mol.GetAtoms()) @@ -49,6 +52,9 @@ class BPol(PolarizabilityBase): __slots__ = () + def description(self): + return "bond polarizability" + def calculate(self): table = self._get_table() diff --git a/mordred/RingCount.py b/mordred/RingCount.py index edd52d68..a2a21ec7 100644 --- a/mordred/RingCount.py +++ b/mordred/RingCount.py @@ -71,6 +71,20 @@ class RingCount(RingCountBase): __slots__ = ("_order", "_greater", "_fused", "_aromatic", "_hetero",) + def description(self): + if self._order is None: + o = "" + elif self._greater: + o = "{}-or-greater-membered ".format(self._order) + else: + o = "{}-membered ".format(self._order) + + return "{}{}{}ring count".format( + o, + "fused " if self._fused else "", + "aromatic " if self._aromatic else "", + ) + @classmethod def preset(cls): for fused in [False, True]: diff --git a/mordred/RotatableBond.py b/mordred/RotatableBond.py index a2e18857..a8e6376b 100644 --- a/mordred/RotatableBond.py +++ b/mordred/RotatableBond.py @@ -21,10 +21,13 @@ def parameters(self): class RotatableBondsCount(RotatableBondsBase): - r"""ratatable bonds count descriptor(rdkit wrapper).""" + r"""rotatable bonds count descriptor(rdkit wrapper).""" __slots__ = () + def description(self): + return "rotatable bonds count" + def __str__(self): return "nRot" @@ -45,6 +48,9 @@ class RotatableBondsRatio(RotatableBondsBase): __slots__ = () + def description(self): + return "rotatable bonds ratio" + def __str__(self): return "RotRatio" diff --git a/mordred/SLogP.py b/mordred/SLogP.py index b842a21e..c5d4468b 100644 --- a/mordred/SLogP.py +++ b/mordred/SLogP.py @@ -34,6 +34,9 @@ class SLogP(WildmanCrippenBase): __slots__ = () + def description(self): + return "Wildman-Crippen LogP" + def calculate(self): return Crippen.MolLogP(self.mol) @@ -43,5 +46,8 @@ class SMR(WildmanCrippenBase): __slots__ = () + def description(self): + return "Wildman-Crippen MR" + def calculate(self): return Crippen.MolMR(self.mol) diff --git a/mordred/TopoPSA.py b/mordred/TopoPSA.py index 3511e3e6..6124e80b 100644 --- a/mordred/TopoPSA.py +++ b/mordred/TopoPSA.py @@ -22,6 +22,11 @@ class TopoPSA(Descriptor): __slots__ = ("_no_only",) + def description(self): + return "topological polar surface area{}".format( + " (use only nitrogen and oxygen)" if self._no_only else "", + ) + @classmethod def preset(cls): yield cls(True) diff --git a/mordred/TopologicalCharge.py b/mordred/TopologicalCharge.py index d95b5a62..1794c748 100644 --- a/mordred/TopologicalCharge.py +++ b/mordred/TopologicalCharge.py @@ -36,7 +36,7 @@ class TopologicalCharge(Descriptor): :type type: str :param type: - * "sum": sum of order-distance atom pairs coefficient + * "raw": sum of order-distance atom pairs coefficient * "mean": mean of order-distance atom pairs coefficient * "global": sum of mean-topoCharge over 0 to order @@ -54,6 +54,12 @@ class TopologicalCharge(Descriptor): tc_types = ("global", "mean", "raw") + def description(self): + return "{}-ordered {} topological charge".format( + self._order, + self._type, + ) + @classmethod def preset(cls): return chain( diff --git a/mordred/TopologicalIndex.py b/mordred/TopologicalIndex.py index 0e71b9ad..0260df2c 100644 --- a/mordred/TopologicalIndex.py +++ b/mordred/TopologicalIndex.py @@ -26,6 +26,9 @@ class Radius(TopologicalIndexBase): __slots__ = () + def description(self): + return "topological radius" + def __str__(self): return "Radius" @@ -41,6 +44,9 @@ class Diameter(TopologicalIndexBase): __slots__ = () + def description(self): + return "topological diameter" + def __str__(self): return "Diameter" @@ -67,6 +73,9 @@ class TopologicalShapeIndex(TopologicalIndexBase): __slots__ = () + def description(self): + return "topological shape index" + def __str__(self): return "TopoShapeIndex" @@ -99,6 +108,9 @@ class PetitjeanIndex(TopologicalShapeIndex): __slots__ = () + def description(self): + return "Petitjean index" + def __str__(self): return "PetitjeanIndex" diff --git a/mordred/VdwVolumeABC.py b/mordred/VdwVolumeABC.py index c467569c..e36ddc1b 100644 --- a/mordred/VdwVolumeABC.py +++ b/mordred/VdwVolumeABC.py @@ -45,6 +45,9 @@ class VdwVolumeABC(Descriptor): __slots__ = () + def description(self): + return "ABC van der waals volume" + compat_atoms = tuple(bondi_radii) @classmethod diff --git a/mordred/VertexAdjacencyInformation.py b/mordred/VertexAdjacencyInformation.py index 2593d008..d5c5d034 100644 --- a/mordred/VertexAdjacencyInformation.py +++ b/mordred/VertexAdjacencyInformation.py @@ -18,6 +18,9 @@ class VertexAdjacencyInformation(Descriptor): __slots__ = () + def description(self): + return "vertex adjacency information" + @classmethod def preset(cls): yield cls() diff --git a/mordred/WalkCount.py b/mordred/WalkCount.py index 1b3361b0..8ea28920 100644 --- a/mordred/WalkCount.py +++ b/mordred/WalkCount.py @@ -23,6 +23,13 @@ class WalkCount(Descriptor): explicit_hydrogens = False + def description(self): + return "{}walk count (leg-{}{})".format( + "total " if self._total else "", + self._order, + ", only self returning walk" if self._self_returning else "", + ) + @classmethod def preset(cls): for start, sr in [(1, False), (2, True)]: diff --git a/mordred/Weight.py b/mordred/Weight.py index cbe47c75..82c44cbb 100644 --- a/mordred/Weight.py +++ b/mordred/Weight.py @@ -14,6 +14,9 @@ class Weight(Descriptor): :param averaged: averaged by number of atom """ + def description(self): + return "{}molecular weight".format("averaged " if self._averaged else "") + __slots__ = ("_averaged",) explicit_hydrogens = True diff --git a/mordred/WienerIndex.py b/mordred/WienerIndex.py index 59dfef79..afb9b673 100644 --- a/mordred/WienerIndex.py +++ b/mordred/WienerIndex.py @@ -14,6 +14,11 @@ class WienerIndex(Descriptor): __slots__ = ("_polarity",) explicit_hydrogens = False + def description(self): + return "Wiener {}index".format( + "polarity " if self._polarity else "", + ) + @classmethod def preset(cls): yield cls(False) diff --git a/mordred/ZagrebIndex.py b/mordred/ZagrebIndex.py index 8e279d74..468a9dab 100644 --- a/mordred/ZagrebIndex.py +++ b/mordred/ZagrebIndex.py @@ -28,12 +28,21 @@ class ZagrebIndex(Descriptor): __slots__ = ("_version", "_variable",) explicit_hydrogens = False + def description(self): + if self._variable == 1: + return "Zagreb index (version {})".format(self._version) + elif self._variable == -1: + return "modified Zagreb index (version {})".format(self._version) + else: + return "Zagreb like index (lambda = {}, version {})".format( + self._variable, self._version) + @classmethod def preset(cls): return (cls(v, x) for x in [1, -1] for v in [1, 2]) def __str__(self): - if self._variable in [1, -1]: + if self._variable in {1, -1}: m = "" if self._variable == 1 else "m" return "{}Zagreb{}".format(m, self._version) @@ -43,7 +52,7 @@ def parameters(self): return self._version, self._variable def __init__(self, version=1, variable=1): - assert version in [1, 2] + assert version in {1, 2} self._version = version self._variable = variable diff --git a/mordred/_base/descriptor.py b/mordred/_base/descriptor.py index d1ec318e..a1c18ad5 100644 --- a/mordred/_base/descriptor.py +++ b/mordred/_base/descriptor.py @@ -59,6 +59,9 @@ class Descriptor(six.with_metaclass(DescriptorMeta, object)): def __reduce_ex__(self, version): return self.__class__, self.parameters() + def description(self): + pass + @classmethod def preset(cls): r"""Generate preset descriptor instances. diff --git a/mordred/_matrix_attributes.py b/mordred/_matrix_attributes.py index 63443035..900e7b05 100644 --- a/mordred/_matrix_attributes.py +++ b/mordred/_matrix_attributes.py @@ -103,6 +103,10 @@ def calculate(self, matrix): class SpAbs(Common): __slots__ = () + @classmethod + def description(cls): + return "graph energy" + def calculate(self, eig): return np.abs(eig.val).sum() @@ -111,6 +115,10 @@ def calculate(self, eig): class SpMax(Common): __slots__ = () + @classmethod + def description(cls): + return "leading eigenvalue" + def calculate(self, eig): return eig.val[eig.max] @@ -119,6 +127,10 @@ def calculate(self, eig): class SpDiam(Common): __slots__ = () + @classmethod + def description(cls): + return "spectral diamiter" + def dependencies(self): return { "SpMax": self._SpMax, @@ -132,6 +144,10 @@ def calculate(self, SpMax, eig): class SpMean(Common): __slots__ = () + @classmethod + def description(cls): + return "mean of eigenvalues" + def calculate(self, eig): return np.mean(eig.val) @@ -140,6 +156,10 @@ def calculate(self, eig): class SpAD(Common): __slots__ = () + @classmethod + def description(cls): + return "spectral absolute diviation" + def dependencies(self): return { "SpMean": self._SpMean, @@ -154,6 +174,10 @@ def calculate(self, eig, SpMean): class SpMAD(Common): __slots__ = () + @classmethod + def description(cls): + return "spectral mean absolute diviation" + def dependencies(self): return {"SpAD": self._SpAD} @@ -165,6 +189,10 @@ def calculate(self, SpAD): class LogEE(Common): __slots__ = () + @classmethod + def description(cls): + return "Estrada-like index" + def calculate(self, eig): # log sum exp: https://hips.seas.harvard.edu/blog/2013/01/09/computing-log-sum-exp a = np.maximum(eig.val[eig.max], 0) @@ -176,6 +204,10 @@ def calculate(self, eig): class SM1(Common): __slots__ = () + @classmethod + def description(cls): + return "spectral moment" + def calculate(self, eig): return eig.val.sum() @@ -184,6 +216,10 @@ def calculate(self, eig): class VE1(Common): __slots__ = () + @classmethod + def description(cls): + return "coefficient sum of the last eigenvector" + def calculate(self, eig): return np.abs(eig.vec[:, eig.max]).sum() @@ -192,6 +228,10 @@ def calculate(self, eig): class VE2(Common): __slots__ = () + @classmethod + def description(cls): + return "average coefficient of the last eigenvector" + def dependencies(self): return {"VE1": self._VE1} @@ -203,6 +243,10 @@ def calculate(self, VE1): class VE3(Common): __slots__ = () + @classmethod + def description(cls): + return "logarithmic coefficient sum of the last eigenvector" + def dependencies(self): return {"VE1": self._VE1} @@ -215,6 +259,10 @@ def calculate(self, VE1): class VR1(Common): __slots__ = () + @classmethod + def description(cls): + return "Randic-like eigenvector-based index" + def calculate(self, eig): s = 0.0 @@ -231,6 +279,10 @@ def calculate(self, eig): class VR2(Common): __slots__ = () + @classmethod + def description(cls): + return "normalized Randic-like eigenvector-based index" + def dependencies(self): return {"VR1": self._VR1} @@ -242,6 +294,10 @@ def calculate(self, VR1): class VR3(Common): __slots__ = () + @classmethod + def description(cls): + return "logarithmic Randic-like eigenvector-based index" + def dependencies(self): return {"VR1": self._VR1} diff --git a/mordred/_util.py b/mordred/_util.py index 7f816bd8..c5d6ccba 100644 --- a/mordred/_util.py +++ b/mordred/_util.py @@ -91,3 +91,14 @@ def PathType(string): def module_prog(pkg): return "{} -m {}".format(os.path.basename(sys.executable), pkg) + + +def to_ordinal(n): + if n == 1: + return "first" + elif n == 2: + return "second" + elif n == 3: + return "third" + else: + return "{}-th".format(n) From 0fdebc856da7ab5a81d1e5f3c03bff7a529c2d54 Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Tue, 22 Aug 2017 01:21:13 +0900 Subject: [PATCH 4/8] update docs to use description --- docs/scripts/gen_default_descs.py | 74 ++++++++++++++++-------- docs/scripts/gen_descriptor_list_xlsx.py | 41 +++++++++++++ docs/subpackages/mordred.descriptors.rst | 2 +- 3 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 docs/scripts/gen_descriptor_list_xlsx.py diff --git a/docs/scripts/gen_default_descs.py b/docs/scripts/gen_default_descs.py index 4fe6d328..6991ba4f 100644 --- a/docs/scripts/gen_default_descs.py +++ b/docs/scripts/gen_default_descs.py @@ -3,7 +3,7 @@ load_path.nop() -prelude = ''' +prelude = """ Descriptor List =============== preset descriptors @@ -13,42 +13,70 @@ calc = Calculator(descriptors) .. csv-table:: Descriptor list - :header: "#", "module", "name", "constructor", "dim" - :widths: 10, 20, 20, 40, 10 + :header: "#", "module", "name", "constructor", "dim", "description" + :widths: 1, 2, 2, 4, 1, 10 -'''[1:] +"""[1:] -def main(out): - out.write(prelude) +class DescriptorInfo(object): + def __init__(self, d): + self.raw = d - i = 0 + @property + def module(self): + return self.raw.__module__ - for mdl in descriptors.all: - mdl_name = '.'.join(mdl.__name__.split('.')) - mdl_ppr = ':py:mod:`~{}`'.format(mdl_name) - first = True + @property + def constructor(self): + return self.raw.__class__.__name__ - for Desc in get_descriptors_from_module(mdl): + @property + def parameters(self): + return [Descriptor._pretty(p) for p in self.raw.parameters()] - for desc in Desc.preset(): - i += 1 + @property + def dimention(self): + return "3D" if self.raw.require_3D else "2D" + + @property + def description(self): + return self.raw.description() + + def to_rst(self, hide_module=False): + mdl = "" if hide_module else ":py:mod:`~{}`".format(self.module) + desc = self.raw + cnst = ":py:class:`~{}.{}` ({})".format( + self.module, self.constructor, ", ".join(self.parameters)) + info = self.description + dim = self.dimention - if not first: - mdl_ppr = '' + return '{}, {}, "{}", {}, "{}"'.format(mdl, desc, cnst, dim, info) - cnst = desc.__class__.__name__ - args = ', '.join(Descriptor._pretty(p) for p in desc.parameters()) - cnst = ':py:class:`~{}.{}` ({})'.format(mdl_name, cnst, args) +def get_all_descriptors(): + for mdl in descriptors.all: + ds = [] + for Desc in get_descriptors_from_module(mdl): + for desc in Desc.preset(): + ds.append(desc) - dim = '3D' if desc.require_3D else '2D' + yield ds - out.write(' {}, {}, {}, "{}", {}\n'.format(i, mdl_ppr, desc, cnst, dim)) - first = False +def main(out): + out.write(prelude) + + i = 0 + + for descs in get_all_descriptors(): + first = True + for desc in descs: + i += 1 + out.write(" {}, {}\n".format(i, DescriptorInfo(desc).to_rst(not first))) + first = False -if __name__ == '__main__': +if __name__ == "__main__": import sys main(sys.stdout) diff --git a/docs/scripts/gen_descriptor_list_xlsx.py b/docs/scripts/gen_descriptor_list_xlsx.py new file mode 100644 index 00000000..dd611e83 --- /dev/null +++ b/docs/scripts/gen_descriptor_list_xlsx.py @@ -0,0 +1,41 @@ +from openpyxl import Workbook +from openpyxl.styles import Font + +from gen_default_descs import DescriptorInfo, get_all_descriptors + + +def main(out): + wb = Workbook() + ws = wb.active + ws.title = "descriptors" + + ws.append(["index", "module", "name", "constructor", "dimention", "description"]) + for cell in ws["1:1"]: + cell.font = Font(bold=True) + + i = 0 + for descs in get_all_descriptors(): + first = True + for desc in descs: + i += 1 + info = DescriptorInfo(desc) + ws.append([ + i, + info.module.split(".")[-1] if first else None, + str(info.raw), + "{}({})".format(info.constructor, ", ".join(info.parameters)), + info.dimention, + info.description, + ]) + first = False + + for cells in ws.columns: + l = max(len(str(cell.value or "")) for cell in cells) + ws.column_dimensions[cells[0].column].width = l + 1 + + wb.save(out) + + +if __name__ == "__main__": + import sys + main(sys.argv[1]) diff --git a/docs/subpackages/mordred.descriptors.rst b/docs/subpackages/mordred.descriptors.rst index 019c171f..0f348824 100644 --- a/docs/subpackages/mordred.descriptors.rst +++ b/docs/subpackages/mordred.descriptors.rst @@ -1,5 +1,5 @@ mordred.descriptors -============= +=================== .. automodule:: mordred.descriptors :members: From 5ea87135deebb70117fb982926ca5a20d483d267 Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Thu, 31 Aug 2017 02:36:42 +0900 Subject: [PATCH 5/8] fix on python2 --- mordred/MolecularDistanceEdge.py | 10 +++++----- mordred/MolecularId.py | 6 +++--- mordred/VdwVolumeABC.py | 4 ++-- mordred/_atomic_property.py | 24 +++++++++++++++++++----- mordred/surface_area/_sasa.py | 4 ++-- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/mordred/MolecularDistanceEdge.py b/mordred/MolecularDistanceEdge.py index 0854a168..d5c6c034 100644 --- a/mordred/MolecularDistanceEdge.py +++ b/mordred/MolecularDistanceEdge.py @@ -3,7 +3,7 @@ from ._base import Descriptor from ._graph_matrix import Valence, DistanceMatrix -from ._atomic_property import table +from ._atomic_property import GetAtomicNumber, GetElementSymbol __all__ = ("MolecularDistanceEdge",) @@ -38,7 +38,7 @@ 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=table.GetElementSymbol(self._atomic_num), + e=GetElementSymbol(self._atomic_num), ) @classmethod @@ -52,13 +52,13 @@ def preset(cls): def __str__(self): return "MDE{}-{}{}".format( - table.GetElementSymbol(self._atomic_num), + GetElementSymbol(self._atomic_num), self._valence1, self._valence2, ) def parameters(self): - return self._valence1, self._valence2, table.GetElementSymbol(self._atomic_num) + return self._valence1, self._valence2, GetElementSymbol(self._atomic_num) def __init__(self, valence1=1, valence2=1, element="C"): self._valence1 = min(valence1, valence2) @@ -66,7 +66,7 @@ def __init__(self, valence1=1, valence2=1, element="C"): if isinstance(element, integer_types): self._atomic_num = element elif isinstance(element, string_types): - self._atomic_num = table.GetAtomicNumber(element) + self._atomic_num = GetAtomicNumber(element) else: raise ValueError("element must be atomic number or atomic symbol") diff --git a/mordred/MolecularId.py b/mordred/MolecularId.py index c1684e3e..27b209c3 100644 --- a/mordred/MolecularId.py +++ b/mordred/MolecularId.py @@ -4,7 +4,7 @@ from networkx import Graph from ._base import Descriptor -from ._atomic_property import table, halogen +from ._atomic_property import GetAtomicNumber, GetElementSymbol, halogen __all__ = ("MolecularId",) @@ -112,7 +112,7 @@ def description(self): else: e = self._type if isinstance(e, integer_types): - e = table.GetAtomicSymbol(e) + e = GetElementSymbol(e) t = " on {} atoms".format(e) @@ -142,7 +142,7 @@ def __init__(self, type="any", averaged=False, _eps=1e-10): self._eps = _eps if isinstance(type, str) and type not in ["any", "hetero", "X"]: - type = table.GetAtomicNumber(type) + type = GetAtomicNumber(type) if type == "any": self._check = lambda _: True diff --git a/mordred/VdwVolumeABC.py b/mordred/VdwVolumeABC.py index e36ddc1b..4ac32976 100644 --- a/mordred/VdwVolumeABC.py +++ b/mordred/VdwVolumeABC.py @@ -3,7 +3,7 @@ from ._base import Descriptor from .BondCount import BondCount from .RingCount import RingCount -from ._atomic_property import table +from ._atomic_property import GetAtomicNumber __all__ = ( "VdwVolumeABC", @@ -28,7 +28,7 @@ atom_contrib = { - table.GetAtomicNumber(s): 4. / 3. * pi * r ** 3 + GetAtomicNumber(s): 4. / 3. * pi * r ** 3 for s, r in bondi_radii.items() } diff --git a/mordred/_atomic_property.py b/mordred/_atomic_property.py index d34ce8bb..cb96cc48 100644 --- a/mordred/_atomic_property.py +++ b/mordred/_atomic_property.py @@ -2,6 +2,7 @@ import os +import six import numpy as np from rdkit import Chem from rdkit.Chem.rdPartialCharges import ComputeGasteigerCharges @@ -107,7 +108,20 @@ def map(self, f): mc_gowan_volume = PeriodicTable.load("mc_gowan_volume.txt") -table = Chem.GetPeriodicTable() + +_table = Chem.GetPeriodicTable() + + +GetElementSymbol = _table.GetElementSymbol + + +if six.PY2: + def GetAtomicNumber(symbol): + if isinstance(symbol, unicode): # noqa: F821 + symbol = str(symbol) + return _table.GetAtomicNumber(symbol) +else: + GetAtomicNumber = _table.GetAtomicNumber # http://dx.doi.org/10.1002%2Fjps.2600721016 @@ -117,7 +131,7 @@ def get_valence_electrons(atom): if N == 1: return 0 - Zv = table.GetNOuterElecs(N) - atom.GetFormalCharge() + Zv = _table.GetNOuterElecs(N) - atom.GetFormalCharge() Z = atom.GetAtomicNum() - atom.GetFormalCharge() hi = atom.GetTotalNumHs() he = sum(1 for a in atom.GetNeighbors() if a.GetAtomicNum() == 1) @@ -150,14 +164,14 @@ def get_core_count(atom): if Z == 1: return 0.0 - Zv = table.GetNOuterElecs(Z) + Zv = _table.GetNOuterElecs(Z) PN = period[Z] return (Z - Zv) / (Zv * (PN - 1)) def get_eta_epsilon(atom): - Zv = table.GetNOuterElecs(atom.GetAtomicNum()) + Zv = _table.GetNOuterElecs(atom.GetAtomicNum()) return 0.3 * Zv - get_core_count(atom) @@ -196,7 +210,7 @@ def get_eta_nonsigma_contribute(bond): def get_eta_beta_delta(atom): if atom.GetIsAromatic() or\ atom.IsInRing() or\ - table.GetNOuterElecs(atom.GetAtomicNum()) - atom.GetTotalValence() <= 0: + _table.GetNOuterElecs(atom.GetAtomicNum()) - atom.GetTotalValence() <= 0: return 0.0 for b in atom.GetNeighbors(): diff --git a/mordred/surface_area/_sasa.py b/mordred/surface_area/_sasa.py index 9b802cae..962eefc4 100644 --- a/mordred/surface_area/_sasa.py +++ b/mordred/surface_area/_sasa.py @@ -6,7 +6,7 @@ from ._mesh import SphereMesh from .._util import atoms_to_numpy -from .._atomic_property import table, vdw_radii +from .._atomic_property import GetAtomicNumber, vdw_radii class SurfaceArea(object): @@ -128,7 +128,7 @@ def from_pdb(cls, pdb, solvent_radius=1.4, level=3): coords = [] for atom in PDBParser().get_structure("", pdb).get_atoms(): - rs.append(vdw_radii[table.GetAtomicNumber(atom.element)] + solvent_radius) + rs.append(vdw_radii[GetAtomicNumber(atom.element)] + solvent_radius) coords.append(atom.coord) return cls(np.array(rs), np.array(coords), level) From 44dd39ee8d8bf60c2419c610970ec855eb1e5c15 Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Thu, 31 Aug 2017 02:41:52 +0900 Subject: [PATCH 6/8] update deploy script --- scripts/after_success.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/after_success.sh b/scripts/after_success.sh index ee3bd798..32577fd7 100755 --- a/scripts/after_success.sh +++ b/scripts/after_success.sh @@ -6,16 +6,19 @@ source ./scripts/add_path.sh [[ -n "$COVERAGE" ]] && coveralls if [[ -z "$TRAVIS_TAG" && -z "$APPVEYOR_REPO_TAG_NAME" ]]; then + LABEL=dev echo $(cat mordred/_version.txt).post1.dev1 > mordred/_version.txt +else + LABEL=main fi conda build . --no-test OUTPUT=`conda build . --output --python $PYTHON_VERSION` if [[ -n "$APPVEYOR" ]]; then - cmd /c "anaconda -t $ANACONDA_CLOUD_TOKEN upload --label main --force $OUTPUT" + cmd /c "anaconda -t $ANACONDA_CLOUD_TOKEN upload --label $LABEL --force $OUTPUT" else - anaconda -t $ANACONDA_CLOUD_TOKEN upload --label main --force $OUTPUT + anaconda -t $ANACONDA_CLOUD_TOKEN upload --label $LABEL --force $OUTPUT fi # documentation From 4681a4a341ad7788f25c5beac5d1b72768508cd3 Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Sat, 2 Sep 2017 22:43:15 +0900 Subject: [PATCH 7/8] fix coverage --- scripts/requirements.txt | 1 + scripts/test_script.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index c67266b9..155eeb4c 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -4,3 +4,4 @@ six>=1.10 tqdm>=3.7.1 pyyaml>=3.11 nose>=1.3 +coverage>=4.4 diff --git a/scripts/test_script.sh b/scripts/test_script.sh index bc347211..281c6685 100755 --- a/scripts/test_script.sh +++ b/scripts/test_script.sh @@ -3,4 +3,4 @@ set -e source ./scripts/add_path.sh -nosetests mordred -q +nosetests mordred -q --with-coverage From e83cd17c46d20a44bac380be10d4d0a273ff7adb Mon Sep 17 00:00:00 2001 From: Hirotomo Moriwaki Date: Sun, 3 Sep 2017 00:17:23 +0900 Subject: [PATCH 8/8] bump version to 0.5.0 --- README.rst | 6 ++++++ mordred/_version.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 84750f2f..3b0dd4dd 100644 --- a/README.rst +++ b/README.rst @@ -184,7 +184,13 @@ Documentation ------------- - `master `__ +- `develop `__ +- `v0.5.0 `__ +- `v0.4.1 `__ +- `v0.4.0 `__ +- `v0.3.2 `__ +- `v0.3.1 `__ - `v0.3.0 `__ - `v0.2.1 `__ - `v0.2.0 `__ diff --git a/mordred/_version.txt b/mordred/_version.txt index 267577d4..8f0916f7 100644 --- a/mordred/_version.txt +++ b/mordred/_version.txt @@ -1 +1 @@ -0.4.1 +0.5.0