def add_dependency_edges(g: Dict[str, Set], variable: str, astnode: libsbml.ASTNode) -> None: """Add the dependency edges to the graph.""" # variable --depends_on--> v2 for k in range(astnode.getNumChildren()): child: libsbml.ASTNode = astnode.getChild(k) if child.getType() == libsbml.AST_NAME: # add to dependency graph if id is not a defined parameter or state variable sid = child.getName() if sid not in filtered_ids: g[variable].add(sid) # recursive adding of children add_dependency_edges(g, variable, child)
def _remove_lambda2(astnode: libsbml.ASTNode) -> libsbml.ASTNode: """Replace lambda function with function expression. Removes the lambda and argument parts from lambda expressions; lambda(x, y, x+y) -> x+y :param formula: SBML formula string :return: formula string """ if astnode.isLambda(): num_children = astnode.getNumChildren() # get function with arguments f = astnode.getChild(num_children - 1) # type: libsbml.ASTNode return f.deepCopy() return astnode
def _get_variables(astnode: libsbml.ASTNode, variables: Set[str] = None) -> Set[str]: """Get variables from ASTNode.""" if variables is None: variables: Set[str] = set() # type: ignore num_children = astnode.getNumChildren() if num_children == 0: if astnode.isName(): name = astnode.getName() variables.add(name) # type: ignore else: for k in range(num_children): child: libsbml.ASTNode = astnode.getChild(k) _get_variables(child, variables=variables) return variables # type: ignore
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() # type: 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
def find_names_in_ast(ast: libsbml.ASTNode, names: Optional[List[str]] = None) -> List[str]: """Find all names in given astnode. Names are the variables in the formula. :param ast: :param names: :return: """ if names is None: names = [] # name for this node if ast.getType() == libsbml.AST_NAME: names.append(ast.getName()) for k in range(ast.getNumChildren()): ast_child = ast.getChild(k) find_names_in_ast(ast_child, names) return names
def add_ast_as_product(self, ast, r): if ast is None: # if there is no parent, return v1. root = r.getKineticLaw().getMath().deepCopy() else: root = ASTNode(AST_PLUS) root.addChild(ast) root.addChild(r.getKineticLaw().getMath().deepCopy()) return root
def ast_info(ast: libsbml.ASTNode) -> None: """Print ASTNode information.""" print(ast) print(ast.getType(), ast.getName())
def add_ast_as_reactant(self, ast, r): if ast is None: # if there is no parent, return -1 * v1. root = ASTNode(AST_TIMES) l = ASTNode() l.setValue(-1.0) root.addChild(l) root.addChild(r.getKineticLaw().getMath().deepCopy()) else: root = ASTNode(AST_MINUS) root.addChild(ast) root.addChild(r.getKineticLaw().getMath().deepCopy()) return root