rdkit.Chem.PropertyMol

Package rdkit :: Package Chem :: Module PropertyMol |
[hide private]
[frames] | no frames]

# Source Code for Module rdkit.Chem.PropertyMol

      1  #
      2  # Copyright (C) 2007-2010 Greg Landrum
      3  # All Rights Reserved
      4  #
      5  from rdkit import Chem
      6
      7
      8 -class PropertyMol(Chem.Mol):
      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
     87 -  def __init__(self, mol):
     88      if not isinstance(mol, Chem.Mol):
     89        return
     90      Chem.Mol.__init__(self, mol)
     91      for pn in mol.GetPropNames(includePrivate=True):
     92        self.SetProp(pn, mol.GetProp(pn))
     93
     94 -  def SetProp(self, nm, val):
     95      Chem.Mol.SetProp(self, nm, str(val))
     96
     97 -  def __getstate__(self):
     98      pDict = {}
     99      for pn in self.GetPropNames(includePrivate=True):
    100        pDict[pn] = self.GetProp(pn)
    101      return {'pkl': self.ToBinary(), 'propD': pDict}
    102
    103 -  def __setstate__(self, stateD):
    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      #  doctest boilerplate
    112      #
    113 -def _test():
    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