File: UnitTestQED.py

package info (click to toggle)
rdkit 202009.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 129,624 kB
  • sloc: cpp: 288,030; python: 75,571; java: 6,999; ansic: 5,481; sql: 1,968; yacc: 1,842; lex: 1,254; makefile: 572; javascript: 461; xml: 229; fortran: 183; sh: 134; cs: 93
file content (127 lines) | stat: -rwxr-xr-x 4,461 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127


from collections import namedtuple
import doctest
import os.path
import unittest

from rdkit import Chem
from rdkit import RDConfig
from rdkit.Chem import QED


doLong = False
TestData = namedtuple('TestData', 'lineNo,smiles,mol,expected')
dataNCI200 = os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data', 'QED', 'NCI_200_qed.csv')
dataRegression = os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data', 'QED', 'Regression_qed.csv')


def load_tests(loader, tests, ignore):
  """ Add the Doctests from the module """
  tests.addTests(doctest.DocTestSuite(QED, optionflags=doctest.ELLIPSIS))
  return tests


class TestCase(unittest.TestCase):

  def testQED(self):
    self.assertEqual(QED.qed.version, '1.1.0',
                     msg='QED version has changed. Update the regression tests if required.')

  def testNCI200(self):
    for d in readTestData(dataNCI200):
      self.assertAlmostEqual(QED.qed(d.mol), d.expected,
                             msg='QED not equal to expected in line {}'.format(d.lineNo))
      # Check that adding hydrogens will not change the result
      # This is currently not the case. Hydrogens change the number of rotatable bonds and the
      # number of alerts.
      mol = Chem.AddHs(d.mol)
      self.assertAlmostEqual(QED.qed(mol), d.expected,
                             msg='QED not equal to expected in line {}'.format(d.lineNo))

  def testRegression(self):
    if not doLong:
      raise unittest.SkipTest('long test')
    for d in readTestData(dataRegression):
      self.assertAlmostEqual(QED.qed(d.mol), d.expected,
                             msg='QED not equal to expected in line {}'.format(d.lineNo))

  def test_properties(self):
    m = Chem.MolFromSmiles('N=C(CCSCc1csc(N=C(N)N)n1)NS(N)(=O)=O')
    p = QED.properties(m)
    self.assertAlmostEqual(p.MW, 337.456)
    self.assertAlmostEqual(p.ALOGP, -0.55833)
    self.assertAlmostEqual(p.HBA, 6)
    self.assertAlmostEqual(p.HBD, 5)
    self.assertAlmostEqual(p.PSA, 173.33)
    self.assertAlmostEqual(p.ROTB, 7)
    self.assertAlmostEqual(p.AROM, 1)
    self.assertAlmostEqual(p.ALERTS, 3)

    p = QED.properties(Chem.AddHs(m))
    self.assertAlmostEqual(p.MW, 337.456)
    self.assertAlmostEqual(p.ALOGP, -0.55833)
    self.assertAlmostEqual(p.HBA, 6)
    self.assertAlmostEqual(p.HBD, 5)
    self.assertAlmostEqual(p.PSA, 173.33)
    self.assertAlmostEqual(p.ROTB, 7)
    self.assertAlmostEqual(p.AROM, 1)
    self.assertAlmostEqual(p.ALERTS, 3)

  def test_examples(self):
    # Paroxetine 0.935
    self.assertAlmostEqual(QED.qed(Chem.MolFromSmiles('c1cc2OCOc2cc1OCC1CNCCC1c1ccc(F)cc1')), 0.934,
                           places=3)
    # Leflunomide 0.929
    self.assertAlmostEqual(QED.qed(Chem.MolFromSmiles('C1=NOC(C)=C1C(=O)Nc1ccc(cc1)C(F)(F)F')),
                           0.911, places=3)
    # Clomipramine 0.779
    self.assertAlmostEqual(QED.qed(Chem.MolFromSmiles('CN(C)CCCN1c2ccccc2CCc2ccc(Cl)cc21')),
                           0.818, places=3)
    # Tegaserod 0.213
    self.assertAlmostEqual(QED.qed(Chem.MolFromSmiles('CCCCCNC(=N)NN=CC1=CNc2ccc(CO)cc21')),
                           0.235, places=3)


def readTestData(filename):
  """ Read test data from file """
  with open(filename, 'r') as f:
    for lineNo, line in enumerate(f, 1):
      if line[0] == '#':
        continue
      smiles, expected = line.strip().split(',')
      mol = Chem.MolFromSmiles(smiles)
      if not mol:
        raise AssertionError('molecule construction failed on line %d' % lineNo)
      yield TestData(lineNo, smiles, mol, float(expected))


def updateTestData():
  """ Update the test data. This should only be done if the method changes! """
  for filename in (dataNCI200, dataRegression,):
    data = list(readTestData(filename))
    with open(filename, 'w') as f:
      print('# Test data for QED descriptor', file=f)
      for d in data:
        expected = QED.qed(d.mol)
        print('{0.smiles},{1}'.format(d, expected), file=f)


if __name__ == '__main__':  # pragma: nocover
  import argparse
  import sys
  parser = argparse.ArgumentParser()
  parser.add_argument('-l', default=False, action='store_true', dest='doLong')
  parser.add_argument('-u', default=False, action='store_true', dest='updateTestData')
  args = parser.parse_args()

  # Handle possible arguments
  doLong = args.doLong
  if args.doLong:
    sys.argv.remove('-l')

  if args.updateTestData:
    updateTestData()
    sys.argv.remove('-u')

  unittest.main()