|
6 | 6 |
|
7 | 7 | import libsbml |
8 | 8 | import sympy as sp |
| 9 | +from sympy.abc import _clash |
9 | 10 |
|
10 | 11 | from ..sbml import ( |
11 | 12 | get_sbml_model, |
@@ -104,34 +105,17 @@ def get_free_parameter_ids_with_values( |
104 | 105 | ar.getVariable() for ar in self.sbml_model.getListOfRules() |
105 | 106 | } |
106 | 107 |
|
107 | | - parser_settings = libsbml.L3ParserSettings( |
108 | | - self.sbml_model, |
109 | | - libsbml.L3P_PARSE_LOG_AS_LOG10, |
110 | | - libsbml.L3P_EXPAND_UNARY_MINUS, |
111 | | - libsbml.L3P_NO_UNITS, |
112 | | - libsbml.L3P_AVOGADRO_IS_CSYMBOL, |
113 | | - libsbml.L3P_COMPARE_BUILTINS_CASE_INSENSITIVE, |
114 | | - None, |
115 | | - libsbml.L3P_MODULO_IS_PIECEWISE, |
116 | | - ) |
117 | | - |
118 | 108 | def get_initial(p): |
119 | 109 | # return the initial assignment value if there is one, and it is a |
120 | 110 | # number; `None`, if there is a non-numeric initial assignment; |
121 | 111 | # otherwise, the parameter value |
122 | 112 | if ia := self.sbml_model.getInitialAssignmentBySymbol(p.getId()): |
123 | | - formula_str = libsbml.formulaToL3StringWithSettings( |
124 | | - ia.getMath(), parser_settings |
| 113 | + sym_expr = sympify_sbml(ia.getMath()) |
| 114 | + return ( |
| 115 | + float(sym_expr.evalf()) |
| 116 | + if sym_expr.evalf().is_Number |
| 117 | + else None |
125 | 118 | ) |
126 | | - try: |
127 | | - return float(formula_str) |
128 | | - except ValueError: |
129 | | - sym_expr = sp.sympify(formula_str) |
130 | | - return ( |
131 | | - float(sym_expr.evalf()) |
132 | | - if sym_expr.evalf().is_Number |
133 | | - else None |
134 | | - ) |
135 | 119 | return p.getValue() |
136 | 120 |
|
137 | 121 | return ( |
@@ -200,3 +184,39 @@ def is_state_variable(self, id_: str) -> bool: |
200 | 184 | or self.sbml_model.getCompartment(id_) is not None |
201 | 185 | or self.sbml_model.getRuleByVariable(id_) is not None |
202 | 186 | ) |
| 187 | + |
| 188 | + |
| 189 | +def sympify_sbml(sbml_obj: libsbml.ASTNode | libsbml.SBase) -> sp.Expr: |
| 190 | + """Convert SBML math expression to sympy expression. |
| 191 | +
|
| 192 | + Parameters |
| 193 | + ---------- |
| 194 | + sbml_obj: |
| 195 | + SBML math element or an SBML object with a math element. |
| 196 | +
|
| 197 | + Returns |
| 198 | + ------- |
| 199 | + The sympy expression corresponding to ``sbml_obj``. |
| 200 | + """ |
| 201 | + ast_node = ( |
| 202 | + sbml_obj |
| 203 | + if isinstance(sbml_obj, libsbml.ASTNode) |
| 204 | + else sbml_obj.getMath() |
| 205 | + ) |
| 206 | + |
| 207 | + parser_settings = libsbml.L3ParserSettings( |
| 208 | + ast_node.getParentSBMLObject().getModel(), |
| 209 | + libsbml.L3P_PARSE_LOG_AS_LOG10, |
| 210 | + libsbml.L3P_EXPAND_UNARY_MINUS, |
| 211 | + libsbml.L3P_NO_UNITS, |
| 212 | + libsbml.L3P_AVOGADRO_IS_CSYMBOL, |
| 213 | + libsbml.L3P_COMPARE_BUILTINS_CASE_INSENSITIVE, |
| 214 | + None, |
| 215 | + libsbml.L3P_MODULO_IS_PIECEWISE, |
| 216 | + ) |
| 217 | + |
| 218 | + formula_str = libsbml.formulaToL3StringWithSettings( |
| 219 | + ast_node, parser_settings |
| 220 | + ) |
| 221 | + |
| 222 | + return sp.sympify(formula_str, locals=_clash) |
0 commit comments