Source code for sbmlutils.converters.mathml

"""Helper functions for evaluation of mathml expressions.

In this namespace all the possible names occuring in formula strings have to be defined.

In build in python are
    *, /, +, -
    and, or, not
"""
from math import *
from typing import Any, Dict, Optional, Tuple

import libsbml


[docs]def product(*args: float) -> float: """Product calculation.""" res = 1.0 for arg in args: res *= arg return res
[docs]def sqr(x: float) -> float: """Square calculation.""" return x * x
[docs]def root(a: float, b: float) -> float: """Root calculation.""" return float(a ** (1.0 / b))
[docs]def xor(*args: float) -> int: """XOR calculation.""" foundZero = 0 foundOne = 0 for a in args: if not a: foundZero = 1 else: foundOne = 1 if foundZero and foundOne: return 1 else: return 0
[docs]def piecewise(*args: float) -> float: """Piecewise calculation.""" Nargs = len(args) for k in range(0, Nargs - 1, 2): if args[k + 1]: return args[k] else: return args[Nargs - 1]
""" def pow(x, y): return x**y def gt(a, b): if a > b: return 1 else: return 0 def lt(a, b): if a < b: return 1 else: return 0 def geq(a, b): if a >= b: return 1 else: return 0 def leq(a, b): if a <= b: return 1 else: return 0 def neq(a, b): if a != b: return 1 else: return 0 def f_not(a): if a == 1: return 0 else: return 1 def f_and(*args): for a in args: if a != 1: return 0 return 1 def f_or(*args): for a in args: if a != 0: return 1 return 0 """
[docs]def evaluableMathML(astnode: libsbml.ASTNode, variables: Optional[Dict] = None) -> str: """Create evaluable python formula string from ASTNode.""" if variables is None: variables = {} # replace variables with provided values for key, value in variables.items(): astnode.replaceArgument(key, libsbml.parseFormula(str(value))) # parse formula settings: libsbml.L3ParserSettings = libsbml.L3ParserSettings() settings.setParseUnits(False) settings.setParseCollapseMinus(True) formula: str = libsbml.formulaToL3StringWithSettings(astnode, settings) # <replacements> formula = formula.replace("&&", "and") formula = formula.replace("||", "or") formula = formula.replace("^", "**") return formula
[docs]def evaluateMathML(astnode: libsbml.ASTNode, variables: Optional[Dict] = None) -> Any: """Evaluate MathML string with given set of variable and parameter values. :param astnode: astnode of MathML string :param variables: dictionary of var : value :return: value of evaluated MathML """ if variables is None: variables = {} formula = evaluableMathML(astnode, variables=variables) print(formula) # return the evaluated formula return eval(formula)
if __name__ == "__main__":
[docs] mathmlStr = """ <math xmlns="http://www.w3.org/1998/Math/MathML"> <piecewise> <piece> <cn type="integer"> 8 </cn> <apply> <lt/> <ci> x </ci> <cn type="integer"> 4 </cn> </apply> </piece> <piece> <cn> 0.1 </cn> <apply> <and/> <apply> <leq/> <cn type="integer"> 4 </cn> <ci> x </ci> </apply> <apply> <lt/> <ci> x </ci> <cn type="integer"> 6 </cn> </apply> </apply> </piece> <otherwise> <cn type="integer"> 8 </cn> </otherwise> </piecewise> </math> """
# evaluate the function with the values astnode = libsbml.readMathMLFromString(mathmlStr) y = 5 res = evaluateMathML(astnode, variables={"x": "y"}) print("Result:", res)