def testNodeTransformer(self): from pyphant.core.AstTransformers import ReplaceName, ReplaceOperator, ReplaceCompare rpn = ReplaceName(self.sampleContainer) import ast exprStr = 'col("i") / (col("t") + col("t"))' expr = compile(exprStr, "<TestCase>", "eval", ast.PyCF_ONLY_AST) replacedExpr = rpn.visit(expr) print rpn.localDict print ast.dump(replacedExpr) rpc = ReplaceCompare(rpn.localDict) factorExpr = rpc.visit(replacedExpr) rpo = ReplaceOperator(rpn.localDict) factorExpr = rpo.visit(factorExpr) print ast.dump(factorExpr)
def calcColumn(self, exprStr, shortname, longname): """ Return an unsealed FieldContainer generated from `exprStr`. Parameters ---------- exprStr : str Expression has to be a string. Specifies the mathematical operations which will be evaluated to generate a new FieldContainer containing the result. `exprStr` may contain FieldContainers, PhysicalQuantities, Booleans and Numbers as well as the operators listed below. shortname : str The `shortname` of the returned FieldContainer. longname : str The `longname`of the returned FieldContainer. Syntax ------ FieldContainer FieldContainers can be adressed by their `shortname`or `longname`. For a FieldContainer with shortname="exampleFC" the syntax within `exprStr` is: col("exampleFC") where `col` stands for column and may be `Col` or `COL` as well. Adressing by `longname` works analogously. PhysicalQuantity Within the expression PhysicalQuantities have to be enquoted: "10kg", "100 m", "5 kg * m / s ** 2" where the whitespaces are optional. Booleans and Numbers Can just be used without quotes or braces within `exprStr`: True, False, 1.2, 10 Operators --------- A list of all implemented operations that can be used within `exprStr` sorted by precedence from lowest precedence (least binding) to highest precedence (most binding): or and not Comparisons: <, <=, >, >=, <>, !=, == Addition and Subtraction: +, - Multiplication, Division: *, / Positive, Negative: +x, -x Not implemented: ~, &, |, **, //, %, <<, >> Examples -------- Some examples of valid expressions will be given. Data: distance = FieldContainer(scipy.array([5., 10., 1.]), Quantity('1.0 m'), longname=u"Distance", shortname=u"s") time = FieldContainer(scipy.array([3., 4., 5.]), Quantity('1.0 s'), longname=u"Time", shortname=u"t") Examplary expressions: exprStr = "col('Distance') / col('Time')" exprStr = "col('Distance') - '1 m'" exprStr = "col('t') >= '4 s'" exprStr = "col('s') > '1 m' and COL('Time') == '3s'" """ exprStr = exprStr or "True" import ast rpn = ReplaceName(self) expr = compile(exprStr, "<calcColumn>", "eval", ast.PyCF_ONLY_AST) replacedExpr = rpn.visit(expr) rpc = ReplaceCompare(rpn.localDict) factorExpr = rpc.visit(replacedExpr) rpo = ReplaceOperator(rpn.localDict) factorExpr = rpo.visit(factorExpr) localDict = dict([(key, value.data) for key, value in rpn.localDict.iteritems()]) numpyDict = {"logical_and": numpy.logical_and, "logical_or": numpy.logical_or, "logical_not": numpy.logical_not} localDict.update(numpyDict) data = eval(compile(factorExpr, "<calcColumn>", "eval"), {}, localDict) unitcalc = UnitCalculator(rpn.localDict) unit, dims = unitcalc.getUnitAndDim(replacedExpr) if dims is None: assert not isinstance(data, numpy.ndarray) for col in self.columns: checkDimensions(col.dimensions[0], self.columns[0].dimensions[0]) shape = self.columns[0].dimensions[0].data.shape if data: data = numpy.ones(shape, dtype=bool) else: data = numpy.zeros(shape, dtype=bool) dims = [self.columns[0].dimensions[0]] field = FieldContainer(data, unit, dimensions=dims, longname=longname, shortname=shortname) return field
def calcColumn(self, exprStr, shortname, longname): """ Return an unsealed FieldContainer generated from `exprStr`. Parameters ---------- exprStr : str Expression has to be a string. Specifies the mathematical operations which will be evaluated to generate a new FieldContainer containing the result. `exprStr` may contain FieldContainers, PhysicalQuantities, Booleans and Numbers as well as the operators listed below. shortname : str The `shortname` of the returned FieldContainer. longname : str The `longname`of the returned FieldContainer. Syntax ------ FieldContainer FieldContainers can be adressed by their `shortname`or `longname`. For a FieldContainer with shortname="exampleFC" the syntax within `exprStr` is: col("exampleFC") where `col` stands for column and may be `Col` or `COL` as well. Adressing by `longname` works analogously. PhysicalQuantity Within the expression PhysicalQuantities have to be enquoted: "10kg", "100 m", "5 kg * m / s ** 2" where the whitespaces are optional. Booleans and Numbers Can just be used without quotes or braces within `exprStr`: True, False, 1.2, 10 Operators --------- A list of all implemented operations that can be used within `exprStr` sorted by precedence from lowest precedence (least binding) to highest precedence (most binding): or and not Comparisons: <, <=, >, >=, <>, !=, == Addition and Subtraction: +, - Multiplication, Division: *, / Positive, Negative: +x, -x Not implemented: ~, &, |, **, //, %, <<, >> Examples -------- Some examples of valid expressions will be given. Data: distance = FieldContainer(scipy.array([5., 10., 1.]), Quantity('1.0 m'), longname=u"Distance", shortname=u"s") time = FieldContainer(scipy.array([3., 4., 5.]), Quantity('1.0 s'), longname=u"Time", shortname=u"t") Examplary expressions: exprStr = "col('Distance') / col('Time')" exprStr = "col('Distance') - '1 m'" exprStr = "col('t') >= '4 s'" exprStr = "col('s') > '1 m' and COL('Time') == '3s'" """ exprStr = exprStr or 'True' import ast rpn = ReplaceName(self) expr = compile(exprStr, "<calcColumn>", 'eval', ast.PyCF_ONLY_AST) replacedExpr = rpn.visit(expr) rpc = ReplaceCompare(rpn.localDict) factorExpr = rpc.visit(replacedExpr) rpo = ReplaceOperator(rpn.localDict) factorExpr = rpo.visit(factorExpr) localDict = dict([(key, value.data) \ for key, value in rpn.localDict.iteritems()]) numpyDict = {'logical_and':numpy.logical_and, 'logical_or':numpy.logical_or, 'logical_not':numpy.logical_not} localDict.update(numpyDict) data = eval(compile(factorExpr, '<calcColumn>', 'eval'), {}, localDict) unitcalc = UnitCalculator(rpn.localDict) unit, dims = unitcalc.getUnitAndDim(replacedExpr) if dims is None: assert not isinstance(data, numpy.ndarray) for col in self.columns: checkDimensions(col.dimensions[0], self.columns[0].dimensions[0]) shape = self.columns[0].dimensions[0].data.shape if data: data = numpy.ones(shape, dtype=bool) else: data = numpy.zeros(shape, dtype=bool) dims = [self.columns[0].dimensions[0]] field = FieldContainer(data, unit, dimensions=dims, longname=longname, shortname=shortname) return field