|
5 | 5 | from typing import Iterable, Optional, Tuple |
6 | 6 |
|
7 | 7 | import libsbml |
| 8 | +import sympy as sp |
8 | 9 |
|
9 | 10 | from ..sbml import ( |
10 | 11 | get_sbml_model, |
@@ -103,10 +104,41 @@ def get_free_parameter_ids_with_values( |
103 | 104 | ar.getVariable() for ar in self.sbml_model.getListOfRules() |
104 | 105 | } |
105 | 106 |
|
| 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 | + def get_initial(p): |
| 119 | + # return the initial assignment value if there is one, and it is a |
| 120 | + # number; `None`, if there is a non-numeric initial assignment; |
| 121 | + # otherwise, the parameter value |
| 122 | + if ia := self.sbml_model.getInitialAssignmentBySymbol(p.getId()): |
| 123 | + formula_str = libsbml.formulaToL3StringWithSettings( |
| 124 | + ia.getMath(), parser_settings |
| 125 | + ) |
| 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 | + return p.getValue() |
| 136 | + |
106 | 137 | return ( |
107 | | - (p.getId(), p.getValue()) |
| 138 | + (p.getId(), initial) |
108 | 139 | for p in self.sbml_model.getListOfParameters() |
109 | 140 | if p.getId() not in rule_targets |
| 141 | + and (initial := get_initial(p)) is not None |
110 | 142 | ) |
111 | 143 |
|
112 | 144 | def get_parameter_ids(self) -> Iterable[str]: |
|
0 commit comments