Package rdkit :: Package Chem :: Module PropertyMol

[hide private]
[frames] | no frames]

# Source Code for Module rdkit.Chem.PropertyMol

      1  # $Id$
      2  #
      3  # Copyright (C) 2007-2010 Greg Landrum
      4  # All Rights Reserved
      5  #
      6  from rdkit import Chem
      7
      8 -class PropertyMol(Chem.Mol):
      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:
     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:
     78     ...   pass
     79
     80
     81
     82    """
     83    __getstate_manages_dict__=True
     84 -  def __init__(self,mol):
     85      if not isinstance(mol,Chem.Mol): return
     86      Chem.Mol.__init__(self,mol)
     87      for pn in mol.GetPropNames(includePrivate=True):
     88        self.SetProp(pn,mol.GetProp(pn))
     89 -  def SetProp(self,nm,val):
     90      Chem.Mol.SetProp(self,nm,str(val))
     91 -  def __getstate__(self):
     92      pDict={}
     93      for pn in self.GetPropNames(includePrivate=True):
     94        pDict[pn] = self.GetProp(pn)
     95      return {'pkl':self.ToBinary(),
     96              'propD':pDict}
     97 -  def __setstate__(self,stateD):
     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  #  doctest boilerplate
    106  #
    107 -def _test():
    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