"""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)