Source code for mira.metamodel.io

"""Input/output functions for metamodels."""
__all__ = ["model_from_json_file", "model_to_json_file",
           "expression_to_mathml", "mathml_to_expression"]

import json
import sympy
from .template_model import TemplateModel, SympyExprStr


[docs]def model_from_json_file(fname) -> TemplateModel: """Return a TemplateModel from a JSON file. Parameters ---------- fname : str or Path A file path. Returns ------- : A TemplateModel deserialized from the JSON file. """ with open(fname, 'r') as fh: return TemplateModel.from_json(json.load(fh))
[docs]def model_to_json_file(model: TemplateModel, fname): """Dump a TemplateModel into a JSON file. Parameters ---------- model : TemplateModel A template model to dump to a JSON file. fname : str or Path A file path to dump the model into. """ with open(fname, 'w') as fh: json.dump(json.loads(model.json()), fh, indent=1)
[docs]def expression_to_mathml(expression: sympy.Expr, *args, **kwargs) -> str: """Convert a sympy expression to MathML string. Here we pay attention to not style underscores and numeric suffixes in special ways. Parameters ---------- expression : A sympy expression to convert. args : list Additional arguments to pass to sympy.mathml. kwargs : dict Additional keyword arguments to pass to sympy.mathml. Returns ------- : A MathML string representing the sympy expression. """ if isinstance(expression, SympyExprStr): expression = expression.args[0] mappings = {} for sym in expression.atoms(sympy.Symbol): name = '|' + str(sym).replace('_', 'QQQ') + '|' mappings[str(sym)] = name expression = expression.subs(sym, sympy.Symbol(name)) mml = sympy.mathml(expression, *args, **kwargs) for old_symbol, new_symbol in mappings.items(): mml = mml.replace(new_symbol, old_symbol) return mml
[docs]def mathml_to_expression(xml_str: str) -> sympy.Expr: """Convert a MathML string to a sympy expression. Parameters ---------- xml_str : A MathML string. Returns ------- : A sympy expression. Notes ----- This function is a wrapper around the SBMLMathMLParser class from the sbmlmath package, which has to be installed. """ from sbmlmath import SBMLMathMLParser template = """<?xml version="1.0" encoding="UTF-8"?> <math xmlns="http://www.w3.org/1998/Math/MathML"> {xml_str} </math>""" xml_str = template.format(xml_str=xml_str) return SBMLMathMLParser().parse_str(xml_str)