File: PropertyMol.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 (131 lines) | stat: -rw-r--r-- 3,261 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
128
129
130
131
#
# Copyright (C) 2007-2010 Greg Landrum
# All Rights Reserved
#
from rdkit import Chem


class PropertyMol(Chem.Mol):
    """ allows rdkit molecules to be pickled with their properties saved.

     >>> import os
     >>> import pickle
     >>> from rdkit import RDConfig
     >>> m = Chem.MolFromMolFile(os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data/benzene.mol'))
     >>> m.GetProp('_Name')
     'benzene.mol'

     by default pickling removes properties:

     >>> m2 = pickle.loads(pickle.dumps(m))
     >>> m2.HasProp('_Name')
     0

     Property mols solve this:

     >>> pm = PropertyMol(m)
     >>> pm.GetProp('_Name')
     'benzene.mol'
     >>> pm.SetProp('MyProp','foo')
     >>> pm.HasProp('MyProp')
     1

     >>> pm2 = pickle.loads(pickle.dumps(pm))
     >>> Chem.MolToSmiles(pm2)
     'c1ccccc1'
     >>> pm2.GetProp('_Name')
     'benzene.mol'
     >>> pm2.HasProp('MyProp')
     1
     >>> pm2.GetProp('MyProp')
     'foo'
     >>> pm2.HasProp('MissingProp')
     0

     Property mols are a bit more permissive about the types
     of property values:

     >>> pm.SetProp('IntVal',1)

     That wouldn't work with a standard mol

     but the Property mols still convert all values to strings before storing:

     >>> pm.GetProp('IntVal')
     '1'

     This is a test for sf.net issue 2880943: make sure properties end up in SD files:

     >>> import tempfile, os
     >>> fn = tempfile.NamedTemporaryFile(suffix='.sdf', delete=False).name
     >>> w = Chem.SDWriter(fn)
     >>> w.write(pm)
     >>> w=None
     >>> with open(fn,'r') as inf:
     ...   txt = inf.read()
     >>> '<IntVal>' in txt
     True
     >>> try:
     ...   os.unlink(fn)
     ... except Exception:
     ...   pass

     The next level of that bug: does writing a *depickled* propertymol
     to an SD file include properties:

     >>> fn = tempfile.NamedTemporaryFile(suffix='.sdf', delete=False).name
     >>> w = Chem.SDWriter(fn)
     >>> pm = pickle.loads(pickle.dumps(pm))
     >>> w.write(pm)
     >>> w=None
     >>> with open(fn,'r') as inf:
     ...   txt = inf.read()
     >>> '<IntVal>' in txt
     True
     >>> try:
     ...   os.unlink(fn)
     ... except Exception:
     ...   pass



    """
    __getstate_manages_dict__ = True

    def __init__(self, mol):
        if not isinstance(mol, Chem.Mol):
            return
        Chem.Mol.__init__(self, mol)
        for pn in mol.GetPropNames(includePrivate=True):
            self.SetProp(pn, mol.GetProp(pn))

    def SetProp(self, nm, val):
        Chem.Mol.SetProp(self, nm, str(val))

    def __getstate__(self):
        pDict = {}
        for pn in self.GetPropNames(includePrivate=True):
            pDict[pn] = self.GetProp(pn)
        return {'pkl': self.ToBinary(), 'propD': pDict}

    def __setstate__(self, stateD):
        Chem.Mol.__init__(self, stateD['pkl'])
        for prop, val in stateD['propD'].items():
            self.SetProp(prop, val)

        # ------------------------------------
        #
        #  doctest boilerplate
        #


def _test():
    import doctest
    import sys
    return doctest.testmod(sys.modules["__main__"], optionflags=doctest.ELLIPSIS)


if __name__ == '__main__':
    import sys
    failed, tried = _test()
    sys.exit(failed)