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