# $Id$ # # Copyright (C) 2001-2006 greg Landrum and Rational Discovery LLC # # @@ All Rights Reserved @@ # This file is part of the RDKit. # The contents are covered by the terms of the BSD license # which is included in the file license.txt, found at the root # of the RDKit source tree. # """ Calculation of Lipinski parameters for molecules """ #from Chem import rdchem from rdkit import Chem from rdkit.Chem import rdMolDescriptors #----------------------------------- # on import build the SMARTS patterns so we only have to do it once #----------------------------------- # The Daylight SMARTS expressions for # recognizing H-bond donors and acceptors in the Lipinski scheme. # HDonor '[!#6;!H0;-0]' # HAcceptor '[$([!#6;+0]);!$([F,Cl,Br,I]); # !$([o,s,nX3]);!$([Nv5,Pv5,Sv4,Sv6])]' # Heteroatom '[B,N,O,P,S,F,Cl,Br,I]' # 2 definitions adapted from those in the Gobbi Paper # NOTE: if you want traditional Lipinski numbers, you # should use NOCounts (below) instead of HAcceptor # HDonorSmarts = Chem.MolFromSmarts('[$([N;!H0;v3]),$([N;!H0;+1;v4]),$([O,S;H1;+0]),$([n;H1;+0])]') # changes log for HAcceptorSmarts: # v2, 1-Nov-2008, GL : fix amide-N exclusion; remove Fs from definition HAcceptorSmarts = Chem.MolFromSmarts('[$([O,S;H1;v2]-[!$(*=[O,N,P,S])]),\ $([O,S;H0;v2]),$([O,S;-]),\ $([N;v3;!$(N-*=!@[O,N,P,S])]),\ $([nH0,o,s;+0])\ ]') HeteroatomSmarts = Chem.MolFromSmarts('[!#6;!#1]') # NOTE: the Rotatable bond smarts here doesn't treat deuteriums (which are left in the graph # and therefore contribute to the degree of a carbon) the same as hydrogens (which are removed # from the graph). So the bond in [2H]C([2H])([2H])C([2H])([2H])[2H] *is* considered # rotatable. RotatableBondSmarts = Chem.MolFromSmarts('[!$(*#*)&!D1]-&!@[!$(*#*)&!D1]') NHOHSmarts = Chem.MolFromSmarts('[#8H1,#7H1,#7H2,#7H3]') NOCountSmarts = Chem.MolFromSmarts('[#7,#8]') # this little trick saves duplicated code def _NumMatches(mol,smarts): return len(mol.GetSubstructMatches(smarts,uniquify=1)) NumHDonors = lambda x:rdMolDescriptors.CalcNumHBD(x) NumHDonors.__doc__="Number of Hydrogen Bond Donors" NumHDonors.version="1.0.0" _HDonors = lambda x,y=HDonorSmarts:x.GetSubstructMatches(y,uniquify=1) NumHAcceptors = lambda x:rdMolDescriptors.CalcNumHBA(x) NumHAcceptors.__doc__="Number of Hydrogen Bond Acceptors" NumHAcceptors.version="2.0.0" _HAcceptors = lambda x,y=HAcceptorSmarts:x.GetSubstructMatches(y,uniquify=1) NumHeteroatoms = lambda x:rdMolDescriptors.CalcNumHeteroatoms(x) NumHeteroatoms.__doc__="Number of Heteroatoms" NumHeteroatoms.version="1.0.0" _Heteroatoms = lambda x,y=HeteroatomSmarts:x.GetSubstructMatches(y,uniquify=1) NumRotatableBonds = lambda x:rdMolDescriptors.CalcNumRotatableBonds(x) NumRotatableBonds.__doc__="Number of Rotatable Bonds" NumRotatableBonds.version="1.0.0" _RotatableBonds = lambda x,y=RotatableBondSmarts:x.GetSubstructMatches(y,uniquify=1) NOCount = lambda x:rdMolDescriptors.CalcNumLipinskiHBA(x) NOCount.__doc__="Number of Nitrogens and Oxygens" NOCount.version="1.0.0" NHOHCount = lambda x:rdMolDescriptors.CalcNumLipinskiHBD(x) NHOHCount.__doc__="Number of NHs or OHs" NHOHCount.version="2.0.0" RingCount=lambda x:rdMolDescriptors.CalcNumRings(x) RingCount.version = "1.0.0" def HeavyAtomCount(mol): " Number of heavy atoms a molecule." return mol.GetNumHeavyAtoms() HeavyAtomCount.version = "1.0.1" _bulkConvert=("CalcFractionCSP3","CalcNumAromaticRings","CalcNumSaturatedRings","CalcNumAromaticHeterocycles", "CalcNumAromaticCarbocycles","CalcNumSaturatedHeterocycles","CalcNumSaturatedCarbocycles","CalcNumAliphaticRings", "CalcNumAliphaticHeterocycles","CalcNumAliphaticCarbocycles") for txt in _bulkConvert: _cfn = getattr(rdMolDescriptors,txt) _fn = lambda x,y=_cfn:y(x) try: _fn.version=getattr(rdMolDescriptors,"_"+txt+"_version") except AttributeError: pass _fn.__doc__=_cfn.__doc__ nm = txt.replace("Calc","") locals()[nm]=_fn