1
2
3
4
5
6 from rdkit import Chem
7
9 """ allows rdkit molecules to be pickled with their properties saved.
10
11 >>> 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 >>> m.SetProp('IntVal',1)
47 Traceback (most recent call last):
48 ...
49 ArgumentError: Python argument types in
50 Mol.SetProp(Mol, str, int)
51 did not match C++ signature:
52 ...
53
54 but the Property mols still convert all values to strings before storing:
55 >>> pm.GetProp('IntVal')
56 '1'
57
58 This is a test for sf.net issue 2880943: make sure properties end up in SD files:
59 >>> import tempfile,os
60 >>> fn = tempfile.mktemp('.sdf')
61 >>> w = Chem.SDWriter(fn)
62 >>> w.write(pm)
63 >>> w=None
64 >>> txt = file(fn,'r').read()
65 >>> '<IntVal>' in txt
66 True
67 >>> try:
68 ... os.unlink(fn)
69 ... except:
70 ... pass
71
72 The next level of that bug: does writing a *depickled* propertymol
73 to an SD file include properties:
74 >>> fn = tempfile.mktemp('.sdf')
75 >>> w = Chem.SDWriter(fn)
76 >>> pm = cPickle.loads(cPickle.dumps(pm))
77 >>> w.write(pm)
78 >>> w=None
79 >>> txt = file(fn,'r').read()
80 >>> '<IntVal>' in txt
81 True
82 >>> try:
83 ... os.unlink(fn)
84 ... except:
85 ... pass
86
87
88
89 """
90 __getstate_manages_dict__=True
99 pDict={}
100 for pn in self.GetPropNames(includePrivate=True):
101 pDict[pn] = self.GetProp(pn)
102 return {'pkl':self.ToBinary(),
103 'propD':pDict}
105 Chem.Mol.__init__(self,stateD['pkl'])
106 for prop,val in stateD['propD'].iteritems():
107 self.SetProp(prop,val)
108
109
110
111
112
113
115 import doctest,sys
116 return doctest.testmod(sys.modules["__main__"],optionflags=doctest.ELLIPSIS)
117
118 if __name__ == '__main__':
119 import sys
120 failed,tried = _test()
121 sys.exit(failed)
122