Package rdkit :: Package Chem :: Module Descriptors
[hide private]
[frames] | no frames]

Source Code for Module rdkit.Chem.Descriptors

  1  # 
  2  # Copyright (C) 2001-2017 greg Landrum and Rational Discovery LLC 
  3  # 
  4  #   @@ All Rights Reserved @@ 
  5  #  This file is part of the RDKit. 
  6  #  The contents are covered by the terms of the BSD license 
  7  #  which is included in the file license.txt, found at the root 
  8  #  of the RDKit source tree. 
  9  # 
 10  import collections 
 11   
 12  from rdkit import Chem 
 13  from rdkit.Chem import rdMolDescriptors as _rdMolDescriptors 
 14  from rdkit.Chem import rdPartialCharges, rdMolDescriptors 
 15  import rdkit.Chem.ChemUtils.DescriptorUtilities as _du 
 16  from rdkit.Chem.EState.EState import (MaxEStateIndex, MinEStateIndex, 
 17                                        MaxAbsEStateIndex, MinAbsEStateIndex) 
 18  from rdkit.Chem.QED import qed 
 19   
 20   
21 -def _isCallable(thing):
22 return (hasattr(collections, 'Callable') and isinstance(thing, collections.Callable)) or \ 23 hasattr(thing, '__call__')
24 25 26 _descList = [] 27 28
29 -def _setupDescriptors(namespace):
30 global _descList, descList 31 from rdkit.Chem import GraphDescriptors, MolSurf, Lipinski, Fragments, Crippen, Descriptors3D 32 from rdkit.Chem.EState import EState_VSA 33 mods = [GraphDescriptors, MolSurf, EState_VSA, Lipinski, Crippen, Fragments] 34 35 otherMods = [Chem] 36 37 for nm, thing in namespace.items(): 38 if nm[0] != '_' and _isCallable(thing): 39 _descList.append((nm, thing)) 40 41 others = [] 42 for mod in otherMods: 43 tmp = dir(mod) 44 for name in tmp: 45 if name[0] != '_': 46 thing = getattr(mod, name) 47 if _isCallable(thing): 48 others.append(name) 49 50 for mod in mods: 51 tmp = dir(mod) 52 53 for name in tmp: 54 if name[0] != '_' and name[-1] != '_' and name not in others: 55 # filter out python reference implementations: 56 if name[:2] == 'py' and name[2:] in tmp: 57 continue 58 if name == 'print_function': 59 continue 60 thing = getattr(mod, name) 61 if _isCallable(thing): 62 namespace[name] = thing 63 _descList.append((name, thing)) 64 descList = _descList
65 66 67 MolWt = lambda *x, **y: _rdMolDescriptors._CalcMolWt(*x, **y) 68 MolWt.version = _rdMolDescriptors._CalcMolWt_version 69 MolWt.__doc__ = """The average molecular weight of the molecule 70 71 >>> MolWt(Chem.MolFromSmiles('CC')) 72 30.07 73 >>> MolWt(Chem.MolFromSmiles('[NH4+].[Cl-]')) 74 53.49... 75 76 """ 77 78 HeavyAtomMolWt = lambda x: MolWt(x, True) 79 HeavyAtomMolWt.__doc__ = """The average molecular weight of the molecule ignoring hydrogens 80 81 >>> HeavyAtomMolWt(Chem.MolFromSmiles('CC')) 82 24.02... 83 >>> HeavyAtomMolWt(Chem.MolFromSmiles('[NH4+].[Cl-]')) 84 49.46 85 86 """ 87 HeavyAtomMolWt.version = "1.0.0" 88 89 ExactMolWt = lambda *x, **y: _rdMolDescriptors.CalcExactMolWt(*x, **y) 90 ExactMolWt.version = _rdMolDescriptors._CalcExactMolWt_version 91 ExactMolWt.__doc__ = """The exact molecular weight of the molecule 92 93 >>> ExactMolWt(Chem.MolFromSmiles('CC')) 94 30.04... 95 >>> ExactMolWt(Chem.MolFromSmiles('[13CH3]C')) 96 31.05... 97 98 """ 99 100
101 -def NumValenceElectrons(mol):
102 """ The number of valence electrons the molecule has 103 104 >>> NumValenceElectrons(Chem.MolFromSmiles('CC')) 105 14 106 >>> NumValenceElectrons(Chem.MolFromSmiles('C(=O)O')) 107 18 108 >>> NumValenceElectrons(Chem.MolFromSmiles('C(=O)[O-]')) 109 18 110 >>> NumValenceElectrons(Chem.MolFromSmiles('C(=O)')) 111 12 112 113 """ 114 tbl = Chem.GetPeriodicTable() 115 return sum( 116 tbl.GetNOuterElecs(atom.GetAtomicNum()) - atom.GetFormalCharge() + atom.GetTotalNumHs() 117 for atom in mol.GetAtoms())
118 119 120 NumValenceElectrons.version = "1.1.0" 121 122
123 -def NumRadicalElectrons(mol):
124 """ The number of radical electrons the molecule has 125 (says nothing about spin state) 126 127 >>> NumRadicalElectrons(Chem.MolFromSmiles('CC')) 128 0 129 >>> NumRadicalElectrons(Chem.MolFromSmiles('C[CH3]')) 130 0 131 >>> NumRadicalElectrons(Chem.MolFromSmiles('C[CH2]')) 132 1 133 >>> NumRadicalElectrons(Chem.MolFromSmiles('C[CH]')) 134 2 135 >>> NumRadicalElectrons(Chem.MolFromSmiles('C[C]')) 136 3 137 138 """ 139 return sum(atom.GetNumRadicalElectrons() for atom in mol.GetAtoms())
140 141 142 NumRadicalElectrons.version = "1.1.0" 143 144
145 -def _ChargeDescriptors(mol, force=False):
146 if not force and hasattr(mol, '_chargeDescriptors'): 147 return mol._chargeDescriptors 148 chgs = rdPartialCharges.ComputeGasteigerCharges(mol) 149 minChg = 500. 150 maxChg = -500. 151 for at in mol.GetAtoms(): 152 chg = float(at.GetProp('_GasteigerCharge')) 153 minChg = min(chg, minChg) 154 maxChg = max(chg, maxChg) 155 res = (minChg, maxChg) 156 mol._chargeDescriptors = res 157 return res
158 159
160 -def MaxPartialCharge(mol, force=False):
161 _, res = _ChargeDescriptors(mol, force) 162 return res
163 164 165 MaxPartialCharge.version = "1.0.0" 166 167
168 -def MinPartialCharge(mol, force=False):
169 res, _ = _ChargeDescriptors(mol, force) 170 return res
171 172 173 MinPartialCharge.version = "1.0.0" 174 175
176 -def MaxAbsPartialCharge(mol, force=False):
177 v1, v2 = _ChargeDescriptors(mol, force) 178 return max(abs(v1), abs(v2))
179 180 181 MaxAbsPartialCharge.version = "1.0.0" 182 183
184 -def MinAbsPartialCharge(mol, force=False):
185 v1, v2 = _ChargeDescriptors(mol, force) 186 return min(abs(v1), abs(v2))
187 188 189 MinAbsPartialCharge.version = "1.0.0" 190 191
192 -def _FingerprintDensity(mol, func, *args, **kwargs):
193 fp = func(*((mol,) + args), **kwargs) 194 if hasattr(fp, 'GetNumOnBits'): 195 val = fp.GetNumOnBits() 196 else: 197 val = len(fp.GetNonzeroElements()) 198 return float(val) / mol.GetNumHeavyAtoms()
199 200 201 FpDensityMorgan1 = lambda x: _FingerprintDensity(x, _rdMolDescriptors.GetMorganFingerprint, 1) 202 FpDensityMorgan2 = lambda x: _FingerprintDensity(x, _rdMolDescriptors.GetMorganFingerprint, 2) 203 FpDensityMorgan3 = lambda x: _FingerprintDensity(x, _rdMolDescriptors.GetMorganFingerprint, 3) 204 _du.setDescriptorVersion('1.0.0')(FpDensityMorgan1) 205 _du.setDescriptorVersion('1.0.0')(FpDensityMorgan2) 206 _du.setDescriptorVersion('1.0.0')(FpDensityMorgan3) 207 208 _setupDescriptors(locals()) 209 210
211 -class PropertyFunctor(rdMolDescriptors.PythonPropertyFunctor):
212 """Creates a python based property function that can be added to the 213 global property list. To use, subclass this class and override the 214 __call__ method. Then create an instance and add it to the 215 registry. The __call__ method should return a numeric value. 216 217 Example: 218 219 class NumAtoms(Descriptors.PropertyFunctor): 220 def __init__(self): 221 Descriptors.PropertyFunctor.__init__(self, "NumAtoms", "1.0.0") 222 def __call__(self, mol): 223 return mol.GetNumAtoms() 224 225 numAtoms = NumAtoms() 226 rdMolDescriptors.Properties.RegisterProperty(numAtoms) 227 """ 228
229 - def __init__(self, name, version):
230 rdMolDescriptors.PythonPropertyFunctor.__init__(self, self, name, version)
231
232 - def __call__(self, mol):
233 raise NotImplementedError("Please implement the __call__ method")
234 235 236 # ------------------------------------ 237 # 238 # doctest boilerplate 239 #
240 -def _runDoctests(verbose=None): # pragma: nocover
241 import sys 242 import doctest 243 failed, _ = doctest.testmod(optionflags=doctest.ELLIPSIS, verbose=verbose) 244 sys.exit(failed) 245 246 247 if __name__ == '__main__': # pragma: nocover 248 _runDoctests() 249