File: test_monlib.py

package info (click to toggle)
gemmi 0.7.4%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,644 kB
  • sloc: cpp: 64,445; python: 5,425; ansic: 4,545; sh: 374; makefile: 112; javascript: 86; f90: 42
file content (137 lines) | stat: -rwxr-xr-x 5,962 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python

import os
import unittest
import gemmi

SO2_FROM_MONOMER = """\
CRYST1    1.000    1.000    1.000  90.00  90.00  90.00 P 1                      
HETATM    1  S   SO3     1      -5.979   0.717  17.353  1.00 20.00           S  
HETATM    2  O1  SO3     1      -5.035   1.876  17.325  1.00 20.00           O  
HETATM    3  O2  SO3     1      -7.003   1.053  16.315  1.00 20.00           O1-
HETATM    4  O3  SO3     1      -5.199  -0.407  16.748  1.00 20.00           O1-
"""  # noqa: W291 - trailing whitespace

def full_path(filename):
    return os.path.join(os.path.dirname(__file__), filename)

# tests for make_structure_from_chemcomp_block()
class TestChemCompXyz(unittest.TestCase):
    def test_reading_monomer_SO3_coordinates(self):
        path = full_path('SO3.cif')
        block = gemmi.cif.read(path)[-1]
        st = gemmi.make_structure_from_chemcomp_block(block)
        out = st.make_pdb_string(gemmi.PdbWriteOptions(minimal=True))
        self.assertEqual(out.splitlines(), SO2_FROM_MONOMER.splitlines())

    # comparing HEM.cif from PDB CCD with HEM.pdb from PDBe
    def test_reading_HEM(self):
        cif_path = full_path('HEM.cif')
        cif_block = gemmi.cif.read(cif_path).sole_block()

        cif_st = gemmi.make_structure_from_chemcomp_block(cif_block)
        self.assertEqual(len(cif_st), 2)  # two models: Ideal and Example

        which = gemmi.ChemCompModel.Xyz
        cif_st = gemmi.make_structure_from_chemcomp_block(cif_block, which)
        self.assertEqual(len(cif_st), 0)

        which = gemmi.ChemCompModel.Xyz | gemmi.ChemCompModel.Ideal
        cif_st = gemmi.make_structure_from_chemcomp_block(cif_block, which)
        self.assertEqual(len(cif_st), 1)

        # PDBe files have residue number 0 and ATOM instead of HETATM
        residue = cif_st[0][0][0]
        residue.seqid.num = 0
        residue.het_flag = 'A'
        for atom in residue:
            atom.b_iso = 20
        minimal_opt = gemmi.PdbWriteOptions(minimal=True)
        cif_out = cif_st.make_pdb_string(minimal_opt)
        pdb_path = full_path('HEM.pdb')
        pdb_st = gemmi.read_structure(pdb_path)
        pdb_out = pdb_st.make_pdb_string(minimal_opt)
        self.assertEqual(cif_out.splitlines(), pdb_out.splitlines())

    # HEN.cif from CCD does not provide ideal coordinates
    def test_reading_HEN(self):
        path = full_path('HEN.cif')
        block = gemmi.cif.read(path).sole_block()
        st = gemmi.make_structure_from_chemcomp_block(block)
        self.assertEqual(len(st), 1)

# tests for gemmi/chemcomp.hpp
class TestChemComp(unittest.TestCase):
    def test_hem_ccd(self):
        path = os.path.join(os.path.dirname(__file__), 'HEM.cif')
        block = gemmi.cif.read(path).sole_block()
        cc = gemmi.make_chemcomp_from_block(block)
        self.assertEqual(len(cc.atoms), 75)
        self.assertEqual(len(cc.rt.bonds), 82)
        bond = cc.rt.get_bond("CGA", "O1A")
        self.assertEqual(bond.type, gemmi.BondType.Double)
        self.assertEqual(bond.aromatic, False)
        bond = cc.rt.get_bond("NA", "C1A")
        self.assertEqual(bond.type, gemmi.BondType.Single)
        self.assertEqual(bond.aromatic, True)

    def test_hen_ccd(self):
        path = os.path.join(os.path.dirname(__file__), 'HEN.cif')
        block = gemmi.cif.read(path).sole_block()
        cc = gemmi.make_chemcomp_from_block(block)
        self.assertEqual(len(cc.atoms), 45)
        self.assertEqual(len(cc.rt.bonds), 45)

    def test_so2_ccp4(self):
        path = os.path.join(os.path.dirname(__file__), 'SO3.cif')
        block = gemmi.cif.read(path)[-1]
        cc = gemmi.make_chemcomp_from_block(block)
        self.assertEqual(len(cc.atoms), 4)
        self.assertEqual(len(cc.rt.bonds), 3)
        self.assertAlmostEqual(cc.rt.get_bond("S", "O2").value, 1.496)
        self.assertAlmostEqual(cc.rt.get_bond("O3", "S").esd, 0.019)
        with self.assertRaises(RuntimeError):
            cc.rt.get_bond("O2", "O3")

    def test_shortest_path(self):
        path = full_path('HEM.cif')
        block = gemmi.cif.read(path)[-1]
        cc = gemmi.make_chemcomp_from_block(block)
        A = gemmi.Restraints.AtomId
        result = cc.rt.find_shortest_path(A('FE'), A('CMD'), [])
        self.assertEqual([aid.atom for aid in result],
                         ['FE', 'ND', 'C1D', 'C2D', 'CMD'])
        result = cc.rt.find_shortest_path(A('CMD'), A('FE'), [])
        self.assertEqual([aid.atom for aid in result],
                         ['CMD', 'C2D', 'C1D', 'ND', 'FE'])
        result = cc.rt.find_shortest_path(A('FE'), A('CMD'), [A('C1D')])
        self.assertEqual([aid.atom for aid in result],
                         ['FE', 'ND', 'C4D', 'C3D', 'C2D', 'CMD'])

class TestMonLib(unittest.TestCase):
    def test_path(self):
        path = full_path('')
        monlib = gemmi.read_monomer_lib(path, [])
        self.assertEqual(monlib.path('ALA'), path + "a/ALA.cif")
        self.assertEqual(monlib.path('CON'), path + "c/CON_CON.cif")

    @unittest.skipIf(os.getenv('CLIBD_MON') is None, "$CLIBD_MON not defined.")
    def test_read_monomer_lib(self):
        st = gemmi.read_structure(full_path('4oz7.pdb'))
        resnames = st[0].get_all_residue_names()
        monlib = gemmi.MonLib()
        ok = monlib.read_monomer_lib(os.environ['CLIBD_MON'], resnames)
        self.assertTrue(ok)
        monlib.update_old_atom_names(st)
        topo = gemmi.prepare_topology(st, monlib, model_index=0)
        topo = gemmi.prepare_topology(st, monlib, model_index=0,
                                      h_change=gemmi.HydrogenChange.Shift)
        self.assertIsNotNone(topo)
        # topo = gemmi.prepare_topology(st, monlib, model_index=0,
        #                              h_change=gemmi.HydrogenChange.ReAdd)
        # RuntimeError: Placing of hydrogen bonded to A/22W 6/N failed:
        # Missing angle restraint HN-N-C.


if __name__ == '__main__':
    unittest.main()