1
2
3
4
5 from rdkit import Chem
6
7
9 """ allows rdkit molecules to be pickled with their properties saved.
10
11 >>> import os
12 >>> from rdkit.six.moves import cPickle
13 >>> from rdkit import RDConfig
14 >>> m = Chem.MolFromMolFile(os.path.join(RDConfig.RDCodeDir, 'Chem', 'test_data/benzene.mol'))
15 >>> m.GetProp('_Name')
16 'benzene.mol'
17
18 by default pickling removes properties:
19 >>> m2 = cPickle.loads(cPickle.dumps(m))
20 >>> m2.HasProp('_Name')
21 0
22
23 Property mols solve this:
24 >>> pm = PropertyMol(m)
25 >>> pm.GetProp('_Name')
26 'benzene.mol'
27 >>> pm.SetProp('MyProp','foo')
28 >>> pm.HasProp('MyProp')
29 1
30
31 >>> pm2 = cPickle.loads(cPickle.dumps(pm))
32 >>> Chem.MolToSmiles(pm2)
33 'c1ccccc1'
34 >>> pm2.GetProp('_Name')
35 'benzene.mol'
36 >>> pm2.HasProp('MyProp')
37 1
38 >>> pm2.GetProp('MyProp')
39 'foo'
40 >>> pm2.HasProp('MissingProp')
41 0
42
43 Property mols are a bit more permissive about the types
44 of property values:
45 >>> pm.SetProp('IntVal',1)
46
47 That wouldn't work with a standard mol
48
49 but the Property mols still convert all values to strings before storing:
50 >>> pm.GetProp('IntVal')
51 '1'
52
53 This is a test for sf.net issue 2880943: make sure properties end up in SD files:
54 >>> import tempfile,os
55 >>> fn = tempfile.mktemp('.sdf')
56 >>> w = Chem.SDWriter(fn)
57 >>> w.write(pm)
58 >>> w=None
59 >>> txt = open(fn,'r').read()
60 >>> '<IntVal>' in txt
61 True
62 >>> try:
63 ... os.unlink(fn)
64 ... except Exception:
65 ... pass
66
67 The next level of that bug: does writing a *depickled* propertymol
68 to an SD file include properties:
69 >>> fn = tempfile.mktemp('.sdf')
70 >>> w = Chem.SDWriter(fn)
71 >>> pm = cPickle.loads(cPickle.dumps(pm))
72 >>> w.write(pm)
73 >>> w=None
74 >>> txt = open(fn,'r').read()
75 >>> '<IntVal>' in txt
76 True
77 >>> try:
78 ... os.unlink(fn)
79 ... except Exception:
80 ... pass
81
82
83
84 """
85 __getstate_manages_dict__ = True
86
93
96
98 pDict = {}
99 for pn in self.GetPropNames(includePrivate=True):
100 pDict[pn] = self.GetProp(pn)
101 return {'pkl': self.ToBinary(), 'propD': pDict}
102
104 Chem.Mol.__init__(self, stateD['pkl'])
105 for prop, val in stateD['propD'].items():
106 self.SetProp(prop, val)
107
108
109
110
111
112
114 import doctest, sys
115 return doctest.testmod(sys.modules["__main__"], optionflags=doctest.ELLIPSIS)
116
117
118 if __name__ == '__main__':
119 import sys
120 failed, tried = _test()
121 sys.exit(failed)
122