File: test_io_sdf.py

package info (click to toggle)
openstructure 2.11.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 206,256 kB
  • sloc: cpp: 188,571; python: 36,686; ansic: 34,298; fortran: 3,275; sh: 312; xml: 146; makefile: 29
file content (117 lines) | stat: -rw-r--r-- 4,284 bytes parent folder | download
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
import unittest
from ost import *
import subprocess

class TestSDF(unittest.TestCase):
  def setUp(self):
    pass

  def test_LoadEntity(self):
    ent = io.LoadSDF('testfiles/sdf/compound.sdf')
    self.assertEqual(len(ent.chains), 4)
    self.assertEqual(len(ent.atoms), 180)
    self.assertEqual(len(ent.bonds), 188)

  def test_LoadEntity_crlf(self):
    ent = io.LoadSDF('testfiles/sdf/6d5w_rank1_crlf.sdf.gz')
    self.assertEqual(len(ent.atoms), 21)
    self.assertEqual(len(ent.bonds), 24)

  def test_Charge(self):
    ent = io.LoadSDF('testfiles/sdf/simple.sdf')
    self.assertEqual(ent.FindAtom("00001_Simple Ligand", 1, "6").charge,  0)

    # Write and read charges properly
    for chg in range(-3, 4):
      ent.FindAtom("00001_Simple Ligand", 1, "6").charge = chg
      sdf_str = io.EntityToSDFStr(ent)
      ent = io.SDFStrToEntity(sdf_str)
      self.assertEqual(ent.FindAtom("00001_Simple Ligand", 1, "6").charge,  chg)

    # Only -3 to +3 is supported
    # If M CHG is implemented the following tests can be removed
    with self.assertRaises(Exception):
      ent.FindAtom("00001_Simple Ligand", 1, "6").charge = 4
      io.EntityToSDFStr(ent)

    with self.assertRaises(Exception):
      ent.FindAtom("00001_Simple Ligand", 1, "6").charge = -4
      io.EntityToSDFStr(ent)

  def test_MChg(self):
    ent = io.LoadSDF('testfiles/sdf/m_chg.sdf')
    n_at = ent.FindAtom("00001_Simple Ligand", 1, "1")
    self.assertEqual(n_at.charge, 1)
    cl_at = ent.FindAtom("00001_Simple Ligand", 1, "6")
    self.assertEqual(cl_at.charge, -1)
    # Charge from atom line is ignored
    o_at = ent.FindAtom("00001_Simple Ligand", 1, "3")
    self.assertEqual(o_at.charge, 0)

  def test_fault_tolerant(self):
    """This file has a "dative" bond (type = 9).
    This is a non-standard extension from RDKit which should go through only
    in fault tolerant mode"""

    with self.assertRaises(Exception):
      ent = io.LoadSDF('testfiles/sdf/dative_bond.sdf')

    # Directly with fault_tolerant
    PushVerbosityLevel(-1)  # Expect message at Error level
    ent = io.LoadSDF('testfiles/sdf/dative_bond.sdf', fault_tolerant=True)
    PopVerbosityLevel()
    self.assertEqual(ent.FindAtom("00001_Simple Ligand", 1, "5").bonds[0].bond_order, 9)

    # Sloppy profile
    PushVerbosityLevel(-1)  # Expect message at Error level
    ent = io.LoadSDF('testfiles/sdf/dative_bond.sdf', profile="SLOPPY")
    PopVerbosityLevel()
    self.assertEqual(ent.FindAtom("00001_Simple Ligand", 1, "5").bonds[0].bond_order, 9)

    # Sloppy profile set as default
    old_profile = io.profiles['DEFAULT'].Copy()
    io.profiles['DEFAULT'] = "SLOPPY"
    PushVerbosityLevel(-1)  # Expect message at Error level
    ent = io.LoadSDF('testfiles/sdf/dative_bond.sdf')
    PopVerbosityLevel()
    self.assertEqual(ent.FindAtom("00001_Simple Ligand", 1, "5").bonds[0].bond_order, 9)

    # Test that a restored default profile has fault_tolerant again
    io.profiles['DEFAULT'] = old_profile
    with self.assertRaises(Exception):
      ent = io.LoadSDF('testfiles/sdf/dative_bond.sdf')

  def test_bond_types(self):
    """Test that bond types are properly converted to V2000 format."""
    v3000_ent = io.LoadSDF('testfiles/sdf_v3000/bcl.sdf')
    # Find the magnesium atom:
    mg_at = v3000_ent.FindAtom("00001_BCL", 1, "12")
    for bond in mg_at.bonds:
      if bond.first == v3000_ent.FindAtom("00001_BCL", 1, "11"):
        self.assertEqual(bond.bond_order, 9)
        break
    else:
      raise Exception("Magnesium atom partner (N 11) not found")
    
    # Now we know we have a coordination bond, we can write it out to SDFV2000:
    PushVerbosityLevel(0)  # Expect message at Warning level
    v2000_str = io.EntityToSDFStr(v3000_ent)
    PopVerbosityLevel()
    # We can read it without fault_tolerant
    v2000_ent = io.SDFStrToEntity(v2000_str)
    # Mg atom has been converted to a single bond:
    v2000_mg_at = v2000_ent.FindAtom("00001_BCL", 1, "12")
    for bond in v2000_mg_at.bonds:
      if bond.first == v2000_ent.FindAtom("00001_BCL", 1, "11"):
        self.assertEqual(bond.bond_order, 1)
        break
    else:
      raise Exception("Magnesium atom partner (N 11) not found")


if __name__== '__main__':
  from ost import testutils
  testutils.RunTests()