Source code for openmdao.lib.casehandlers.filters

"""
Case filters provide a means to select cases based on their index in the
sequence of cases or the case data values.
"""

import math
import sys

from zope.interface import implements

from openmdao.main.interfaces import ICaseFilter


# This dict will act as the local scope when we eval our expressions.
_EXPR_DICT = {'math': math}
# Add stuff from math lib directly to our locals dict so users won't have to
# put 'math.' in front of all of their calls to standard math functions.
for name in dir(math):
    if not name.startswith('_'):
        _EXPR_DICT[name] = getattr(math, name)
# Make numpy functions available if possible.
try:
    import numpy
except ImportError:
    pass
else:
    _EXPR_DICT['numpy'] = numpy


[docs]class IteratorCaseFilter(object): """ Select based on an iterator of case numbers. iterator: iterator Provides case numbers, assumed to be in increasing order. """ implements(ICaseFilter) def __init__(self, iterator): self._iterator = iterator self._current = None self._next()
[docs] def select(self, seqno, case): """ Return True if `case` should be used. seqno: int Case sequence number. case: Case Case to be checked. """ if self._current is None: return False while seqno > self._current: self._next() if self._current is None: return False if seqno < self._current: return False else: self._next() return True
def _next(self): """ Set `_current` to next value in sequence, or None. """ old = self._current try: self._current = self._iterator.next() except StopIteration: self._current = None else: if old is not None and self._current <= old: raise RuntimeError('non-increasing sequence at %s,%s' % (old, self._current))
[docs]class SequenceCaseFilter(IteratorCaseFilter): """ Select based on a sequence of case numbers. indices: sequence(int) Sequence of case numbers, assumed to be in increasing order. """ def __init__(self, indices): super(SequenceCaseFilter, self).__init__(iter(indices))
[docs]class SliceCaseFilter(IteratorCaseFilter): """ Select based on `start`, `stop`, and `step` of case numbers. start: int Starting case number. stop: int Ending case number. step: int Step between case numbers. """ def __init__(self, start=0, stop=sys.maxint, step=1): super(SliceCaseFilter, self).__init__(iter(xrange(start, stop, step)))
[docs]class ExprCaseFilter(object): """ Select based on a boolean Python expression of the case data or ``seqno``. Case data is accessed by ``case['name']`` expr: string Boolean expression referring to the case data or ``seqno``. Examples: - select failed cases ``'case.msg'``. - select first 3 cases: ``'seqno < 3'``. - select case with 'param' between 2 and 2.5: \ ``'case["param"] > 2 and case["param"] < 2.5'``. """ implements(ICaseFilter) def __init__(self, expr): self.expr = expr def __getstate__(self): """Return dict representing this container's state.""" state = self.__dict__.copy() # Compiled stuff doesn't pickle state['_code'] = None def __setstate__(self, state): """Restore this component's state.""" self.__dict__.update(state) self._code = compile(self._expr, '<string>', 'eval') @property def expr(self): """ The expression to be evaluated. """ return self._expr @expr.setter
[docs] def expr(self, value): """ Set the expression and compile it. """ self._expr = value try: self._code = compile(self._expr, '<string>', 'eval') except Exception as exc: raise type(exc)("Can't compile expression %r: %s" % (self._expr, exc))
[docs] def select(self, seqno, case): """ Return True if `case` should be used. seqno: int Case sequence number. case: Case Case to be checked. """ try: return eval(self._code, _EXPR_DICT, dict(seqno=seqno, case=case)) except Exception as exc: raise type(exc)("Can't evaluate expression %r: %s" % (self._expr, exc))
OpenMDAO Home