rdkit.VLib.Filter

Package rdkit :: Package VLib :: Module Filter |
[hide private]
[frames] | no frames]

# Source Code for Module rdkit.VLib.Filter

      1  #  $Id$
      2  #
      3  #  Copyright (C) 2003 Rational Discovery LLC
      4  #     All Rights Reserved
      5  #
      6
      7  from rdkit import six
      8  from rdkit.VLib.Node import VLibNode
      9
     10
     11 -class FilterNode(VLibNode):
     12    """ base class for nodes which filter their input
     13
     14    Assumptions:
     15
     16      - filter function takes a number of arguments equal to the
     17        number of inputs we have.  It returns a bool
     18
     19      - inputs (parents) can be stepped through in lockstep
     20
     21      - we return a tuple if there's more than one input
     22
     23    Usage Example:
     24      >>> from rdkit.VLib.Supply import SupplyNode
     25      >>> def func(a,b):
     26      ...   return a+b < 5
     27      >>> filt = FilterNode(func=func)
     28      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     29      >>> suppl2 = SupplyNode(contents=[1,2,3,1])
     30      >>> filt.AddParent(suppl1)
     31      >>> filt.AddParent(suppl2)
     32      >>> v = [x for x in filt]
     33      >>> v
     34      [(1, 1), (2, 2), (3, 1)]
     35      >>> filt.reset()
     36      >>> v = [x for x in filt]
     37      >>> v
     38      [(1, 1), (2, 2), (3, 1)]
     39      >>> filt.Destroy()
     40
     41      Negation is also possible:
     42      >>> filt = FilterNode(func=func,negate=1)
     43      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     44      >>> suppl2 = SupplyNode(contents=[1,2,3,1])
     45      >>> filt.AddParent(suppl1)
     46      >>> filt.AddParent(suppl2)
     47      >>> v = [x for x in filt]
     48      >>> v
     49      [(3, 3)]
     50      >>> filt.Destroy()
     51
     52      With no function, just return the inputs:
     53      >>> filt = FilterNode()
     54      >>> suppl1 = SupplyNode(contents=[1,2,3,3])
     55      >>> filt.AddParent(suppl1)
     56      >>> v = [x for x in filt]
     57      >>> v
     58      [1, 2, 3, 3]
     59      >>> filt.Destroy()
     60
     61
     62
     63    """
     64
     65 -  def __init__(self, func=None, negate=0, **kwargs):
     66      VLibNode.__init__(self, **kwargs)
     67      self._func = func
     68      self._negate = negate
     69
     70 -  def SetNegate(self, state):
     71      self._negate = state
     72
     73 -  def Negate(self):
     74      return self._negate
     75
     76 -  def next(self):
     77      parents = self.GetParents()
     78      while 1:
     79        args = []
     80        try:
     81          for parent in parents:
     82            args.append(next(parent))
     83        except StopIteration:
     84          raise StopIteration
     85        args = tuple(args)
     86        if self._func is not None:
     87          r = self._func(*args)
     88          if self._negate:
     89            r = not r
     90            # sys.stderr.write('\t\tNEGATE -> %d\n'%(r))
     91          if r:
     92            res = args
     93            break
     94        else:
     95          res = args
     96          break
     97      if len(parents) == 1:
     98        res = res[0]
     99      return res
    100
    101
    102  if six.PY3:
    103    FilterNode.__next__ = FilterNode.next
    104
    105
    106  # ------------------------------------
    107  #
    108  #  doctest boilerplate
    109  #
    110 -def _runDoctests(verbose=None):  # pragma: nocover
    111    import sys
    112    import doctest
    113    failed, _ = doctest.testmod(optionflags=doctest.ELLIPSIS, verbose=verbose)
    114    sys.exit(failed)
    115
    116
    117  if __name__ == '__main__':  # pragma: nocover
    118    _runDoctests()
    119