├── qed ├── __init__.py └── qed.py ├── .gitignore ├── dist ├── uamc-qed-1.0.2.tar.gz └── uamc_qed-1.0.2-py3-none-any.whl ├── how_to_make_distribution.txt ├── LICENSE ├── setup.py └── README.md /qed/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = ["qed"] 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | qed.egg-info/ 2 | build/ 3 | uamc_qed.egg-info/ 4 | -------------------------------------------------------------------------------- /dist/uamc-qed-1.0.2.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silicos-it/qed/HEAD/dist/uamc-qed-1.0.2.tar.gz -------------------------------------------------------------------------------- /dist/uamc_qed-1.0.2-py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silicos-it/qed/HEAD/dist/uamc_qed-1.0.2-py3-none-any.whl -------------------------------------------------------------------------------- /how_to_make_distribution.txt: -------------------------------------------------------------------------------- 1 | > python setup.py sdist 2 | 3 | This creates a 'dist/' folder in which the tar distribution is located. 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup, find_packages 4 | 5 | with open("README.md", "r") as fh: 6 | long_description = fh.read() 7 | 8 | version = {} 9 | with open("qed/qed.py") as fp: 10 | exec(fp.read(), version) 11 | 12 | setup( 13 | name = "uamc-qed", 14 | version = version['__version__'], 15 | author = "Hans De Winter", 16 | author_email = "hans.dewinter@uantwerpen.be", 17 | description = ("Python implementation of the QED descriptor (Quantitative Estimation of Druglikeness)"), 18 | long_description = long_description, 19 | long_description_content_type="text/markdown", 20 | url = "https://github.com/UAMCAntwerpen/qed", 21 | download_url = "https://github.com/UAMCAntwerpen/qed/releases/tag/1.0.2", 22 | packages = find_packages(include=['qed']), 23 | keywords = ['uamc', 'qed', 'rdkit', 'cheminformatics'], 24 | classifiers = [ 25 | "Development Status :: 5 - Production/Stable", 26 | "Environment :: Console", 27 | "Intended Audience :: Science/Research", 28 | "License :: Freeware", 29 | "Operating System :: POSIX :: Linux", 30 | "Operating System :: MacOS :: MacOS X", 31 | "Programming Language :: Python :: 3", 32 | "Topic :: Scientific/Engineering :: Chemistry", 33 | "Topic :: Software Development :: Libraries :: Python Modules", 34 | ], 35 | python_requires = ">=3.6", 36 | ) 37 | -------------------------------------------------------------------------------- /qed/qed.py: -------------------------------------------------------------------------------- 1 | # Copyright 2012 by Silicos-it, a division of Imacosi BVBA 2 | # Copyright 2020- by UAMC, the Medicinal Chemistry department of the University 3 | # of Antwerp 4 | 5 | 6 | __all__ = ['weights_max', 'weights_mean', 'weights_none', 'default'] 7 | __version__ = "1.0.2" 8 | 9 | 10 | # RDKit 11 | from rdkit.Chem import Descriptors 12 | from rdkit import Chem 13 | 14 | # General 15 | from copy import deepcopy 16 | from math import exp, log 17 | import sys, os 18 | 19 | 20 | # 21 | AliphaticRings = Chem.MolFromSmarts('[$([A;R][!a])]') 22 | 23 | 24 | # 25 | AcceptorSmarts = [ 26 | '[oH0;X2]', 27 | '[OH1;X2;v2]', 28 | '[OH0;X2;v2]', 29 | '[OH0;X1;v2]', 30 | '[O-;X1]', 31 | '[SH0;X2;v2]', 32 | '[SH0;X1;v2]', 33 | '[S-;X1]', 34 | '[nH0;X2]', 35 | '[NH0;X1;v3]', 36 | '[$([N;+0;X3;v3]);!$(N[C,S]=O)]' 37 | ] 38 | Acceptors = [] 39 | for hba in AcceptorSmarts: 40 | Acceptors.append(Chem.MolFromSmarts(hba)) 41 | 42 | 43 | 44 | # 45 | StructuralAlertSmarts = [ 46 | '*1[O,S,N]*1', 47 | '[S,C](=[O,S])[F,Br,Cl,I]', 48 | '[CX4][Cl,Br,I]', 49 | '[C,c]S(=O)(=O)O[C,c]', 50 | '[$([CH]),$(CC)]#CC(=O)[C,c]', 51 | '[$([CH]),$(CC)]#CC(=O)O[C,c]', 52 | 'n[OH]', 53 | '[$([CH]),$(CC)]#CS(=O)(=O)[C,c]', 54 | 'C=C(C=O)C=O', 55 | 'n1c([F,Cl,Br,I])cccc1', 56 | '[CH1](=O)', 57 | '[O,o][O,o]', 58 | '[C;!R]=[N;!R]', 59 | '[N!R]=[N!R]', 60 | '[#6](=O)[#6](=O)', 61 | '[S,s][S,s]', 62 | '[N,n][NH2]', 63 | 'C(=O)N[NH2]', 64 | '[C,c]=S', 65 | '[$([CH2]),$([CH][CX4]),$(C([CX4])[CX4])]=[$([CH2]),$([CH][CX4]),$(C([CX4])[CX4])]', 66 | 'C1(=[O,N])C=CC(=[O,N])C=C1', 67 | 'C1(=[O,N])C(=[O,N])C=CC=C1', 68 | 'a21aa3a(aa1aaaa2)aaaa3', 69 | 'a31a(a2a(aa1)aaaa2)aaaa3', 70 | 'a1aa2a3a(a1)A=AA=A3=AA=A2', 71 | 'c1cc([NH2])ccc1', 72 | '[Hg,Fe,As,Sb,Zn,Se,se,Te,B,Si,Na,Ca,Ge,Ag,Mg,K,Ba,Sr,Be,Ti,Mo,Mn,Ru,Pd,Ni,Cu,Au,Cd,Al,Ga,Sn,Rh,Tl,Bi,Nb,Li,Pb,Hf,Ho]', 73 | 'I', 74 | 'OS(=O)(=O)[O-]', 75 | '[N+](=O)[O-]', 76 | 'C(=O)N[OH]', 77 | 'C1NC(=O)NC(=O)1', 78 | '[SH]', 79 | '[S-]', 80 | 'c1ccc([Cl,Br,I,F])c([Cl,Br,I,F])c1[Cl,Br,I,F]', 81 | 'c1cc([Cl,Br,I,F])cc([Cl,Br,I,F])c1[Cl,Br,I,F]', 82 | '[CR1]1[CR1][CR1][CR1][CR1][CR1][CR1]1', 83 | '[CR1]1[CR1][CR1]cc[CR1][CR1]1', 84 | '[CR2]1[CR2][CR2][CR2][CR2][CR2][CR2][CR2]1', 85 | '[CR2]1[CR2][CR2]cc[CR2][CR2][CR2]1', 86 | '[CH2R2]1N[CH2R2][CH2R2][CH2R2][CH2R2][CH2R2]1', 87 | '[CH2R2]1N[CH2R2][CH2R2][CH2R2][CH2R2][CH2R2][CH2R2]1', 88 | 'C#C', 89 | '[OR2,NR2]@[CR2]@[CR2]@[OR2,NR2]@[CR2]@[CR2]@[OR2,NR2]', 90 | '[$([N+R]),$([n+R]),$([N+]=C)][O-]', 91 | '[C,c]=N[OH]', 92 | '[C,c]=NOC=O', 93 | '[C,c](=O)[CX4,CR0X3,O][C,c](=O)', 94 | 'c1ccc2c(c1)ccc(=O)o2', 95 | '[O+,o+,S+,s+]', 96 | 'N=C=O', 97 | '[NX3,NX4][F,Cl,Br,I]', 98 | 'c1ccccc1OC(=O)[#6]', 99 | '[CR0]=[CR0][CR0]=[CR0]', 100 | '[C+,c+,C-,c-]', 101 | 'N=[N+]=[N-]', 102 | 'C12C(NC(N1)=O)CSC2', 103 | 'c1c([OH])c([OH,NH2,NH])ccc1', 104 | 'P', 105 | '[N,O,S]C#N', 106 | 'C=C=O', 107 | '[Si][F,Cl,Br,I]', 108 | '[SX2]O', 109 | '[SiR0,CR0](c1ccccc1)(c2ccccc2)(c3ccccc3)', 110 | 'O1CCCCC1OC2CCC3CCCCC3C2', 111 | 'N=[CR0][N,n,O,S]', 112 | '[cR2]1[cR2][cR2]([Nv3X3,Nv4X4])[cR2][cR2][cR2]1[cR2]2[cR2][cR2][cR2]([Nv3X3,Nv4X4])[cR2][cR2]2', 113 | 'C=[C!r]C#N', 114 | '[cR2]1[cR2]c([N+0X3R0,nX3R0])c([N+0X3R0,nX3R0])[cR2][cR2]1', 115 | '[cR2]1[cR2]c([N+0X3R0,nX3R0])[cR2]c([N+0X3R0,nX3R0])[cR2]1', 116 | '[cR2]1[cR2]c([N+0X3R0,nX3R0])[cR2][cR2]c1([N+0X3R0,nX3R0])', 117 | '[OH]c1ccc([OH,NH2,NH])cc1', 118 | 'c1ccccc1OC(=O)O', 119 | '[SX2H0][N]', 120 | 'c12ccccc1(SC(S)=N2)', 121 | 'c12ccccc1(SC(=S)N2)', 122 | 'c1nnnn1C=O', 123 | 's1c(S)nnc1NC=O', 124 | 'S1C=CSC1=S', 125 | 'C(=O)Onnn', 126 | 'OS(=O)(=O)C(F)(F)F', 127 | 'N#CC[OH]', 128 | 'N#CC(=O)', 129 | 'S(=O)(=O)C#N', 130 | 'N[CH2]C#N', 131 | 'C1(=O)NCC1', 132 | 'S(=O)(=O)[O-,OH]', 133 | 'NC[F,Cl,Br,I]', 134 | 'C=[C!r]O', 135 | '[NX2+0]=[O+0]', 136 | '[OR0,NR0][OR0,NR0]', 137 | 'C(=O)O[C,H1].C(=O)O[C,H1].C(=O)O[C,H1]', 138 | '[CX2R0][NX3R0]', 139 | 'c1ccccc1[C;!R]=[C;!R]c2ccccc2', 140 | '[NX3R0,NX4R0,OR0,SX2R0][CX4][NX3R0,NX4R0,OR0,SX2R0]', 141 | '[s,S,c,C,n,N,o,O]~[n+,N+](~[s,S,c,C,n,N,o,O])(~[s,S,c,C,n,N,o,O])~[s,S,c,C,n,N,o,O]', 142 | '[s,S,c,C,n,N,o,O]~[nX3+,NX3+](~[s,S,c,C,n,N])~[s,S,c,C,n,N]', 143 | '[*]=[N+]=[*]', 144 | '[SX3](=O)[O-,OH]', 145 | 'N#N', 146 | 'F.F.F.F', 147 | '[R0;D2][R0;D2][R0;D2][R0;D2]', 148 | '[cR,CR]~C(=O)NC(=O)~[cR,CR]', 149 | 'C=!@CC=[O,S]', 150 | '[#6,#8,#16][C,c](=O)O[C,c]', 151 | 'c[C;R0](=[O,S])[C,c]', 152 | 'c[SX2][C;!R]', 153 | 'C=C=C', 154 | 'c1nc([F,Cl,Br,I,S])ncc1', 155 | 'c1ncnc([F,Cl,Br,I,S])c1', 156 | 'c1nc(c2c(n1)nc(n2)[F,Cl,Br,I])', 157 | '[C,c]S(=O)(=O)c1ccc(cc1)F', 158 | '[15N]', 159 | '[13C]', 160 | '[18O]', 161 | '[34S]' 162 | ] 163 | StructuralAlerts = [] 164 | for smarts in StructuralAlertSmarts: 165 | StructuralAlerts.append(Chem.MolFromSmarts(smarts)) 166 | 167 | 168 | 169 | # ADS parameters for the 8 molecular properties: [row][column] 170 | # rows[8]: MW, ALOGP, HBA, HBD, PSA, ROTB, AROM, ALERTS 171 | # columns[7]: A, B, C, D, E, F, DMAX 172 | # ALOGP parameters from Gregory Gerebtzoff (2012, Roche) 173 | pads1 = [ [2.817065973, 392.5754953, 290.7489764, 2.419764353, 49.22325677, 65.37051707, 104.9805561], 174 | [0.486849448, 186.2293718, 2.066177165, 3.902720615, 1.027025453, 0.913012565, 145.4314800], 175 | [2.948620388, 160.4605972, 3.615294657, 4.435986202, 0.290141953, 1.300669958, 148.7763046], 176 | [1.618662227, 1010.051101, 0.985094388, 0.000000001, 0.713820843, 0.920922555, 258.1632616], 177 | [1.876861559, 125.2232657, 62.90773554, 87.83366614, 12.01999824, 28.51324732, 104.5686167], 178 | [0.010000000, 272.4121427, 2.558379970, 1.565547684, 1.271567166, 2.758063707, 105.4420403], 179 | [3.217788970, 957.7374108, 2.274627939, 0.000000001, 1.317690384, 0.375760881, 312.3372610], 180 | [0.010000000, 1199.094025, -0.09002883, 0.000000001, 0.185904477, 0.875193782, 417.7253140] ] 181 | # ALOGP parameters from the original publication 182 | pads2 = [ [2.817065973, 392.5754953, 290.7489764, 2.419764353, 49.22325677, 65.37051707, 104.9805561], 183 | [3.172690585, 137.8624751, 2.534937431, 4.581497897, 0.822739154, 0.576295591, 131.3186604], 184 | [2.948620388, 160.4605972, 3.615294657, 4.435986202, 0.290141953, 1.300669958, 148.7763046], 185 | [1.618662227, 1010.051101, 0.985094388, 0.000000001, 0.713820843, 0.920922555, 258.1632616], 186 | [1.876861559, 125.2232657, 62.90773554, 87.83366614, 12.01999824, 28.51324732, 104.5686167], 187 | [0.010000000, 272.4121427, 2.558379970, 1.565547684, 1.271567166, 2.758063707, 105.4420403], 188 | [3.217788970, 957.7374108, 2.274627939, 0.000000001, 1.317690384, 0.375760881, 312.3372610], 189 | [0.010000000, 1199.094025, -0.09002883, 0.000000001, 0.185904477, 0.875193782, 417.7253140] ] 190 | 191 | 192 | 193 | def ads(x, a, b, c, d, e, f, dmax): 194 | return ((a+(b/(1+exp(-1*(x-c+d/2)/e))*(1-1/(1+exp(-1*(x-c-d/2)/f))))) / dmax) 195 | 196 | 197 | 198 | def properties(mol): 199 | """ 200 | Calculates the properties that are required to calculate the QED descriptor. 201 | """ 202 | matches = [] 203 | if (mol is None): 204 | print("Error: in function properties(mol): mol argument is \'None\'") 205 | sys.exit(1) 206 | x = [0] * 8 207 | x[0] = Descriptors.MolWt(mol) # MW 208 | x[1] = Descriptors.MolLogP(mol) # ALOGP 209 | for hba in Acceptors: # HBA 210 | if (mol.HasSubstructMatch(hba)): 211 | matches = mol.GetSubstructMatches(hba) 212 | x[2] += len(matches) 213 | x[3] = Descriptors.NumHDonors(mol) # HBD 214 | x[4] = Descriptors.TPSA(mol) # PSA 215 | x[5] = Descriptors.NumRotatableBonds(mol) # ROTB 216 | x[6] = len(Chem.GetSSSR(Chem.DeleteSubstructs(deepcopy(mol), AliphaticRings))) # AROM 217 | for alert in StructuralAlerts: # ALERTS 218 | if (mol.HasSubstructMatch(alert)): x[7] += 1 219 | return x 220 | 221 | 222 | 223 | def qed(w, p, gerebtzoff): 224 | d = [0.00] * 8 225 | if (gerebtzoff): 226 | for i in range(0, 8): 227 | d[i] = ads(p[i], pads1[i][0], pads1[i][1], pads1[i][2], pads1[i][3], pads1[i][4], pads1[i][5], pads1[i][6]) 228 | else: 229 | for i in range(0, 8): 230 | d[i] = ads(p[i], pads2[i][0], pads2[i][1], pads2[i][2], pads2[i][3], pads2[i][4], pads2[i][5], pads2[i][6]) 231 | t = 0.0 232 | for i in range(0, 8): 233 | t += w[i] * log(d[i]) 234 | return (exp(t / sum(w))) 235 | 236 | 237 | 238 | def weights_max(mol, gerebtzoff = True): 239 | """ 240 | Calculates the QED descriptor using maximal descriptor weights. 241 | """ 242 | props = properties(mol) 243 | return qed([0.50, 0.25, 0.00, 0.50, 0.00, 0.50, 0.25, 1.00], props, gerebtzoff) 244 | 245 | 246 | 247 | def weights_mean(mol, gerebtzoff = True): 248 | """ 249 | Calculates the QED descriptor using average descriptor weights. 250 | """ 251 | props = properties(mol) 252 | return qed([0.66, 0.46, 0.05, 0.61, 0.06, 0.65, 0.48, 0.95], props, gerebtzoff) 253 | 254 | 255 | 256 | def weights_none(mol, gerebtzoff = True): 257 | """ 258 | Calculates the QED descriptor using unit weights. 259 | """ 260 | props = properties(mol) 261 | return qed([1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00], props, gerebtzoff) 262 | 263 | 264 | 265 | def default(mol, gerebtzoff = True): 266 | """ 267 | Calculates the QED descriptor using average descriptor weights and Gregory Gerebtzoff parameters. 268 | """ 269 | return weights_mean(mol, gerebtzoff) 270 | 271 | 272 | 273 | def test_data(): 274 | """ 275 | Returns some test data 276 | """ 277 | return({ 278 | "Abacavir" : "Nc1nc(NC2CC2)c2ncn([C@@H]3C[C@H](CO)C=C3)c2n1", 279 | "Acamprosate" : "CC(=O)NCCCS(O)(=O)=O", 280 | "Acebutolol" : "CCCC(=O)Nc1ccc(OCC(O)CNC(C)C)c(c1)C(C)=O", 281 | "Acetaminophen" : "CC(=O)Nc1ccc(O)cc1", 282 | "Acetazolamide" : "CC(=O)Nc1nnc(s1)S(N)(=O)=O", 283 | "Acetohexamide" : "CC(=O)c1ccc(cc1)S(=O)(=O)NC(=O)NC1CCCCC1", 284 | "Acetophenazine" : "CC(=O)c1ccc2Sc3ccccc3N(CCCN3CCN(CCO)CC3)c2c1", 285 | "Paroxetine" : "Fc4ccc(C1CCNCC1COc3ccc2OCOc2c3)cc4", 286 | "Leflunomide" : "Cc1oncc1C(=O)Nc2ccc(C(F)(F)F)cc2", 287 | "Granisetron" : "CN1C4CCCC1CC(NC(=O)c2nn(C)c3ccccc23)C4", 288 | "Pergolide" : "CCCN2CC(CSC)CC1c3cccc4[nH]cc(CC12)c34", 289 | "Molindone" : "CCc3c(C)[nH]c2CCC(CN1CCOCC1)C(=O)c23", 290 | "ChloramphenicalPalmitate" : "CCCCCCCCCCCCCCCC(=O)OCC(NC(=O)C(Cl)Cl)C(O)c1ccc([N+]([O-])=O)cc1", 291 | "ClindamycinPalmitate" : "CCCCCCCCCCCCCCCOC(=O)C2C(O)C(O)C(C(NC(=O)C1CC(CCC)CN1C)C(C)Cl)OC2SC", 292 | "CandesartanCilexetil" : "CCOc3nc2cccc(C(=O)OC(C)OC(=O)OC1CCCCC1)c2n3Cc6ccc(c4ccccc4c5nn[nH]n5)cc6", 293 | "Chlorprothixene" : "CN(C)CCC=c2c1ccccc1sc3ccc(Cl)cc23", 294 | "Atovaquone" : "O=c3c(O)c(C2CCC(c1ccc(Cl)cc1)CC2)c(=O)c4ccccc34", 295 | "Clomipramine" : "CN(C)CCCN3c1ccccc1CCc2ccc(Cl)cc23", 296 | "Methixene" : "CN4CCCC(CC3c1ccccc1Sc2ccccc23)C4", 297 | "Ethopropazine" : "CCN(CC)C(C)Cn3c1ccccc1sc2ccccc23", 298 | "Famotidine" : "N=C(CCSCc1csc(N=C(N)N)n1)NS(N)(=O)=O", 299 | "Cimetidine" : "CNC(=NCCSCc1nc[nH]c1C)NC#N", 300 | "Tegaserod" : "CCCCCNC(=N)NN=Cc1c[nH]c2ccc(CO)cc12", 301 | "Cefdinir" : "C=CC3=C(C(=O)O)N2C(=O)C(NC(=O)C(=NO)c1csc(N)n1)C2SC3", 302 | "CarbenicillinIndanyl" : "CC5(C)SC4C(NC(=O)C(C(=O)Oc2ccc1CCCc1c2)c3ccccc3)C(=O)N4C5C(=O)O", 303 | }) 304 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QED package 2 | 3 | **QED** stands for quantitative estimation of drug-likeness and the concept has been introduced by Richard Bickerton and coworkers [Bickerton, G.R.; Paolini, G.V.; Besnard, J.; Muresan, S.; Hopkins, A.L. (2012) ‘Quantifying the chemical beauty of drugs’, Nature Chemistry, 4, 90-98](http://dx.doi.org/10.1038/nchem.1243). This module relies on [RDKit](https://www.rdkit.org) as a chem-informatics toolkit. 4 | 5 | ## Introduction 6 | 7 | This section is about installing and using **QED** within your own Python scripts or as a standalone Python tool. 8 | 9 | The empirical rationale of the **QED** measure reflects the underlying distribution of molecular properties including molecular weight, logP, topological polar surface area, number of hydrogen bond donors and acceptors, the number of aromatic rings and rotatable bonds, and the presence of unwanted chemical functionalities. 10 | 11 | The **QED** results as generated by this module are not completely identical to those from the [original publication](http://dx.doi.org/10.1038/nchem.1243). These differences are a consequence of differences within the underlying calculated property calculators used in both methods. For example, discrepancies can be noted in the results from the logP calculations, nevertheless despite the fact that both approaches (Pipeline Pilot in the original publication and RDKit in this implementation) mention to use the [Wildmann and Crippen](http://pubs.acs.org/doi/abs/10.1021/ci990307l) methodology for the calculation of their logP-values. In this respect, Gregory Gerebtzoff has been so kind to perform a refitting of the **QED** parameters with logP values generated by RDKit ([see rdkit-discuss](http://sourceforge.net/mailarchive/forum.php?thread_name=E05E80C886E33E4BA10E5686C606617602FF1D7A14%40RKAMSEM707.emea.roche.com&forum_name=rdkit-discuss)). These refitted values have been implemented in **QED** as the default values; however, the original publication values can still be used if desired. 12 | This section assumes you have installed RDKit correctly and that you are familiar with the basic functions of it. It is also recommended to have read the original [QED publication](http://dx.doi.org/10.1038/nchem.1243). 13 | 14 | ## Installation 15 | 16 | There are two ways to install **QED**. The first one is by download from the `GitHub` repository and installing, and the second way is using Python's standard `pip` approach. Both methods are explained below. 17 | 18 | #### 1. Installing with `pip` 19 | 20 | This is probably the easiest way to install **QED**. First make sure you have `pip` installed: 21 | 22 | ```console 23 | > pip -V 24 | pip 20.0.2 from /Users/hans/anaconda3/envs/rdkit/lib/python3.7/site-packages/pip (python 3.7) 25 | ``` 26 | 27 | If `pip` is not installed, then install it first by following these [pip installation notes](https://pip.pypa.io/en/stable/installing/). 28 | 29 | Now you are ready to install **QED**: 30 | 31 | ```console 32 | > pip install uamc-qed 33 | ``` 34 | 35 | Depending on your `python` location, it might be that you need admin rights. In that case, type: 36 | 37 | ```console 38 | > sudo pip install uamc-qed 39 | ``` 40 | 41 | 42 | #### 2. Alternative manner: download from Github and run `setup.py install` 43 | 44 | Download **QED** from [GitHub](https://github.com/UAMCAntwerpen/qed/releases/tag/1.0.2). In this section we assume you have downloaded the file into your `~/Downloads` directory) and untar this file into this directory: 45 | 46 | ```console 47 | > cd ~/Downloads 48 | > sudo tar -xvf uamc-qed-1.0.2.tar.gz 49 | > cd uamc-qed-1.0.2 50 | ``` 51 | 52 | You should now have a number of files in your `~/Downloads/uamc-qed-1.0.2` directory: 53 | 54 | ```console 55 | > ls -l 56 | qed-1.0.2/ 57 | qed-1.0.2/LICENSE 58 | qed-1.0.2/README.md 59 | qed-1.0.2/dist/ 60 | qed-1.0.2/how_to_make_distribution.txt 61 | qed-1.0.2/qed/ 62 | qed-1.0.2/setup.py 63 | ``` 64 | 65 | Move into the `dist` directory and `untar` again: 66 | 67 | ``` 68 | > cd dist 69 | > tar -xvf qed-1.0.2.tar.gz 70 | > cd qed-1.0.2 71 | ``` 72 | 73 | Now install with Python: 74 | 75 | ```console 76 | > python setup.py install 77 | ``` 78 | 79 | This process creates a `qed` folder with all the `qed` files into your default Python site-package install directory. It might be that you need to get root permissions: 80 | 81 | ```console 82 | > sudo python setup.py install 83 | ``` 84 | 85 | Check your installation by launching `Python`: 86 | 87 | ```python 88 | >>> from qed import qed 89 | >>> from rdkit import Chem 90 | >>> m = Chem.MolFromSmiles('c1ccccc1') 91 | >>> qed.default(m) 92 | 0.44619898311523704 93 | ``` 94 | 95 | ## Using QED 96 | 97 | The `qed()` function takes as argument a RDKit molecule and returns the corresponding QED value calculated from it. 98 | The `qed()` function comes in three flavors, each differing in the relative weight that is imposed on the underlying [molecular descriptors](http://dx.doi.org/10.1038/nchem.1243). These three flavors correspond to the three different **QED** measures that were described in the original publication: 99 | 100 | - QEDw,max using the set of weights that give maximal information content. 101 | - QEDw,mo using the mean weights of the optimal 1,000 weight combinations that give the highest information content. 102 | - QEDw,u with all weights as unity, hence unweighted. 103 | 104 | Specifying the required QED weighting scheme in **QED** is done using the corresponding function: 105 | 106 | - `qed.weights_mean()` uses the mean weighting scheme and corresponds to QEDw,mo. Another name for this function is `qed.default()`. 107 | - `qed.weights_max()` specifies the max weighting scheme and corresponds to QEDw,max. 108 | - `qed.weights_none()` specifies unit weights and corresponds to QEDw,u. 109 | 110 | and exemplified below: 111 | 112 | ```python 113 | >>> from qed import qed 114 | >>> from rdkit import Chem 115 | >>> m = Chem.MolFromSmiles('c1ccccc1') 116 | >>> qed.default(m) 117 | 0.44619898311523704 118 | >>> qed.weights_mean(m) 119 | 0.44619898311523704 120 | >>> qed.weights_max(m) 121 | 0.4733526950948539 122 | >>> qed.weights_none(m) 123 | 0.3047153431243204 124 | ``` 125 | 126 | As already mentioned above, the current implementation of **QED** uses the refitted logP parameters from Gregory Gerebtzoff. However, the original values can still be used by specifying `False` as second argument to the appropriate function call: 127 | 128 | ```python 129 | >>> qed.default(m, False) 130 | 0.4426283718993647 131 | >>> qed.weights_mean(m, False) 132 | 0.4426283718993647 133 | >>> qed.weights_max(m, False) 134 | 0.4706596045646091 135 | >>> qed.weights_none(m, False) 136 | 0.3021185764176498 137 | ``` 138 | 139 | The **QED** module also provides its own test set: 140 | 141 | ```python 142 | >>> test = qed.test_data() 143 | >>> for name in test: print(test[name], name) 144 | ... 145 | Nc1nc(NC2CC2)c2ncn([C@@H]3C[C@H](CO)C=C3)c2n1 Abacavir 146 | CC(=O)NCCCS(O)(=O)=O Acamprosate 147 | CCCC(=O)Nc1ccc(OCC(O)CNC(C)C)c(c1)C(C)=O Acebutolol 148 | CC(=O)Nc1ccc(O)cc1 Acetaminophen 149 | CC(=O)Nc1nnc(s1)S(N)(=O)=O Acetazolamide 150 | CC(=O)c1ccc(cc1)S(=O)(=O)NC(=O)NC1CCCCC1 Acetohexamide 151 | CC(=O)c1ccc2Sc3ccccc3N(CCCN3CCN(CCO)CC3)c2c1 Acetophenazine 152 | Fc4ccc(C1CCNCC1COc3ccc2OCOc2c3)cc4 Paroxetine 153 | Cc1oncc1C(=O)Nc2ccc(C(F)(F)F)cc2 Leflunomide 154 | CN1C4CCCC1CC(NC(=O)c2nn(C)c3ccccc23)C4 Granisetron 155 | CCCN2CC(CSC)CC1c3cccc4[nH]cc(CC12)c34 Pergolide 156 | CCc3c(C)[nH]c2CCC(CN1CCOCC1)C(=O)c23 Molindone 157 | CCCCCCCCCCCCCCCC(=O)OCC(NC(=O)C(Cl)Cl)C(O)c1ccc([N+]([O-])=O)cc1 ChloramphenicalPalmitate 158 | CCCCCCCCCCCCCCCOC(=O)C2C(O)C(O)C(C(NC(=O)C1CC(CCC)CN1C)C(C)Cl)OC2SC ClindamycinPalmitate 159 | CCOc3nc2cccc(C(=O)OC(C)OC(=O)OC1CCCCC1)c2n3Cc6ccc(c4ccccc4c5nn[nH]n5)cc6 CandesartanCilexetil 160 | CN(C)CCC=c2c1ccccc1sc3ccc(Cl)cc23 Chlorprothixene 161 | O=c3c(O)c(C2CCC(c1ccc(Cl)cc1)CC2)c(=O)c4ccccc34 Atovaquone 162 | CN(C)CCCN3c1ccccc1CCc2ccc(Cl)cc23 Clomipramine 163 | CN4CCCC(CC3c1ccccc1Sc2ccccc23)C4 Methixene 164 | CCN(CC)C(C)Cn3c1ccccc1sc2ccccc23 Ethopropazine 165 | N=C(CCSCc1csc(N=C(N)N)n1)NS(N)(=O)=O Famotidine 166 | CNC(=NCCSCc1nc[nH]c1C)NC#N Cimetidine 167 | CCCCCNC(=N)NN=Cc1c[nH]c2ccc(CO)cc12 Tegaserod 168 | C=CC3=C(C(=O)O)N2C(=O)C(NC(=O)C(=NO)c1csc(N)n1)C2SC3 Cefdinir 169 | CC5(C)SC4C(NC(=O)C(C(=O)Oc2ccc1CCCc1c2)c3ccccc3)C(=O)N4C5C(=O)O CarbenicillinIndanyl 170 | ``` 171 | 172 | One can inspect the individual properties that are used to calculate the Qed value by calling the `properties()` function: 173 | 174 | ```python 175 | >>> for name in test: 176 | ... mol = Chem.MolFromSmiles(test[name]) 177 | ... p = qed.properties(mol) 178 | ... print("%6.2f\t%6.3f\t%6d\t%6d\t%6.2f\t%6d\t%6d\t%6d\t%6.3f\t%-s" % (p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],qed.default(mol),name)) 179 | ... 180 | 286.34 1.092 6 3 101.88 4 2 1 0.737 Abacavir 181 | 181.21 -0.600 4 2 83.47 4 0 2 0.467 Acamprosate 182 | 336.43 2.365 5 3 87.66 10 1 1 0.571 Acebutolol 183 | 151.16 1.351 2 2 49.33 1 1 1 0.602 Acetaminophen 184 | 222.25 -0.856 5 2 115.04 2 1 1 0.662 Acetazolamide 185 | 324.40 2.210 4 2 92.34 4 1 1 0.833 Acetohexamide 186 | 411.57 3.492 6 1 47.02 7 2 1 0.688 Acetophenazine 187 | 329.37 3.327 4 1 39.72 4 2 0 0.917 Paroxetine 188 | 270.21 3.254 3 1 55.13 2 2 0 0.896 Leflunomide 189 | 312.42 2.318 3 1 50.16 2 2 0 0.927 Granisetron 190 | 314.50 4.271 2 1 19.03 4 2 0 0.871 Pergolide 191 | 276.38 1.963 3 1 45.33 3 1 0 0.923 Molindone 192 | 561.55 6.941 6 2 118.77 21 1 5 0.056 ChloramphenicalPalmitate 193 | 663.41 6.279 8 3 108.33 22 0 3 0.071 ClindamycinPalmitate 194 | 610.67 6.319 10 1 143.34 10 5 2 0.141 CandesartanCilexetil 195 | 315.87 5.188 2 0 3.24 3 3 0 0.629 Chlorprothixene 196 | 366.84 5.505 3 1 54.37 2 2 0 0.741 Atovaquone 197 | 314.86 4.528 2 0 6.48 4 2 0 0.782 Clomipramine 198 | 309.48 5.015 2 0 3.24 2 2 0 0.735 Methixene 199 | 312.48 5.020 3 0 6.48 5 2 0 0.734 Ethopropazine 200 | 337.46 -0.558 6 5 173.33 7 1 3 0.263 Famotidine 201 | 252.35 0.597 5 3 88.89 5 1 5 0.239 Cimetidine 202 | 301.39 2.298 3 5 96.29 7 2 4 0.235 Tegaserod 203 | 395.42 -0.172 8 4 158.21 5 1 4 0.239 Cefdinir 204 | 494.57 2.496 7 2 113.01 6 2 4 0.274 CarbenicillinIndanyl 205 | >>> print(" MW\t ALOGP\t HBA\t HBD\t PSA\t ROTB\t AROM\tALERTS\t QED\tNAME") 206 | MW ALOGP HBA HBD PSA ROTB AROM ALERTS QED NAME 207 | ``` 208 | 209 | ## Revision history 210 | 211 | #### Version 1.0.2 212 | 213 | - Added to the PyPi repository to enable installation using `pip`. 214 | 215 | #### Version 1.0.1 216 | 217 | - Incorporation of the refitted logP parameters of Gregory Gerebtzoff and making these values default ([rdkit-discuss](http://sourceforge.net/mailarchive/forum.php?thread_name=E05E80C886E33E4BA10E5686C606617602FF1D7A14%40RKAMSEM707.emea.roche.com&forum_name=rdkit-discuss)). 218 | - Modification of the `qed()` function to enable the selection of the original parameters, if desired. 219 | 220 | 221 | ## DOI identifier 222 | 223 | DOI:10.5281/zenodo.4293730 224 | --------------------------------------------------------------------------------